【发布时间】:2016-10-21 17:48:44
【问题描述】:
注意:以下代码实际上可以正常工作,但显示了我自己的解决方案中失败的场景。有关更多信息,请参阅这篇文章的底部。
使用这些类:
public class MainType {
public static readonly MainType One = new MainType();
public static readonly MainType Two = SubType.Two;
}
public sealed class SubType : MainType {
public new static readonly SubType Two = new SubType();
}
获取字段One 和Two:
List<FieldInfo> fieldInfos = typeof(MainType)
.GetFields(BindingFlags.Static | BindingFlags.Public)
.Where(f => typeof(MainType).IsAssignableFrom(f.FieldType))
.ToList();
最后,得到它们的值:
List<MainType> publicMainTypes = fieldInfos
.Select(f => (MainType) f.GetValue(null))
.ToList();
在 LinqPad 或带有上述代码的简单单元测试类中,一切正常。但是在我的解决方案中,我有一些单元测试想要处理这些字段的所有实例,GetValue 可以很好地返回父类型的字段,但是如果父字段应该有子类型的实例,它们总是而是给null! (如果这里发生这种情况,最终列表将是 { One, null } 而不是 { One, Two }。)测试类与这两种类型位于不同的项目中(每种类型都在自己的文件中),但我暂时制作了 一切公开。我已经在其中放置了一个断点并检查了所有我可以检查的内容,并且在 Watch 表达式中完成了与 fieldInfos[1].GetValue(null) 等效的操作,它实际上返回 null,尽管事实上我的主类中有一行完全像第二个来自上述MainType。
怎么了?如何获取子类型字段的所有值?他们怎么可能在没有错误的情况下返回 null?
理论上,也许由于某种原因,由于通过反射访问,子类型的类没有被静态构造,我尝试了
System.Runtime.CompilerServices.RuntimeHelpers
.RunClassConstructor(typeof(SubType).TypeHandle);
在开始之前在顶部,但它没有帮助(SubType 是我项目中的实际子类型类)。
我将继续努力尝试在一个简单的案例中重现这一点,但目前我没有想法。
其他信息
经过一番折腾,代码开始工作了。现在它不再工作了。我正在努力重现触发代码开始工作的原因。
注意:在 Visual Studio 2015 中使用 C# 6.0 以 .Net 4.6.1 为目标。
可重现问题
您可以通过下载此somewhat minimal working example of the problem at github 来使用我的场景的工作(失败)精简版本。
调试单元测试。当异常发生时,单步执行到 GlossaryHelper.cs 的第 20 行,可以在Locals 选项卡中看到GetGlossaryMembers 的返回值。您可以看到索引 3 到 12 为空。
【问题讨论】:
-
@Fredou 标签已添加。
-
@Fredou 是的,抱歉,已添加到帖子末尾。
-
@Fredou 我刚刚在我的精简项目中升级到 4.6.1,我正在尝试对问题进行最低限度的重现。
-
最后一个问题,32 位还是 64 位?
-
@Fredou 平台目标是“任何 CPU”,它是 Windows 的 64 位版本,但不确定正在生成什么类型的 EXE。
标签: c# reflection visual-studio-2015 static c#-6.0