如何实例化内部私有类的PrivateType

我试图为私人内部课程设置unit testing,但收效甚微:

namespace Stats.Model { public class DailyStat { private class DailyStatKey // The one to test { private DateTime date; public DateTime Date { get { return date; } set { date = value.Date; } } public StatType Type { get; set; } public override int GetHashCode() { return Date.Year * 1000000 + Date.Month * 10000 + Date.Day * 100 + (int)Type; } public override bool Equals(object obj) { DailyStatKey otherKey = obj as DailyStatKey; if (otherKey == null) return false; return (this.Date == otherKey.Date && this.StatType == otherKey.StatType); } } } } 

我试过这段代码:

 PrivateType statKeyType = new PrivateType("Stats.Model", "Stats.Model.DailyStat.DailyStatKey"); 

以及

 PrivateType statKeyType = new PrivateType("Stats.Model", "DailyStat.DailyStatKey"); 

无济于事。

程序集的名称是“Stats.Model”,对我来说类型名称看起来也是正确的,但我只是得到一个exception:“System.TypeLoadException:无法加载类型”

那么我做错了什么?

据我所知,PrivateType是基于reflection的,我猜它几乎是针对这种情况的,因为你不能在命名空间的正下方有一个私有类。

编辑:

添加了DailyStatKey的完整实现。 我想测试的是我的GetHashCode方法的唯一性。 正如您所看到的,我尝试将日期+类型放入单个int中。

自己找到了解决方案:

 var parentType = typeof(DailyStat); var keyType = parentType.GetNestedType("DailyKeyStat", BindingFlags.NonPublic); //edited to use GetNestedType instead of just NestedType var privateKeyInstance = new PrivateObject(Activator.CreateInstance(keyType, true)); privateKeyInstance.SetProperty("Date", DateTime.Now); privateKeyInstance.SetProperty("Type", StatType.Foo); var hashCode = (int)privateKeyInstance.Invoke("GetHashCode", null); 

您也可以直接使用PrivateType:

 PrivateType statKeyType = new PrivateType("Stats.Model", "Stats.Model.DailyStat+DailyStatKey"); 

嵌套类具有与其命名空间(即Stats.Model.DailyStat.DailyStatKey)不同的字符串格式,因此用法不明显。

由于它是私有的,因此可以创建实例的唯一类是DailyStat本身。 除非你做到非私人反映(激活器)将是你唯一的选择,如果你想创建类,虽然这不是一个好主意,因为你不能直接使用它,除非你能够把它投射到公众类型或接口

编辑:

由于您正在尝试对unit testing执行此操作,因此您实际上不应该测试此类,因为它是私有的。 您只能通过DailyStat任何公共接口进行DailyStat

您可以在父类上编写公共“GetDailyStatKey”方法。

 public class DailyStat { private class DailyStatKey // The one to test { } public DailyStatKey GetDailyStatKey() { return new DailyStatKey(); } } 

现在你可以写:

 DailyStat v = new DailyStat(); var x = v.GetDailyStatKey();