我有一个与以下情况非常相似的情况:
Get all inherited classes of an abstract class
我有两个继承到基类的类
这是我的基类:
public abstract class InputModule
{
public string ModuleName;
public int NumberOfInputFields;
}
这是第一个继承的类:
public class Module1 : InputModule
{
new public string ModuleName = "FilmMusic";
public new int NumberOfInputFields = 7;
}
秒:
public class Module2 : InputModule
{
new public string ModuleName = "MovieStaffInfo";
public new int NumberOfInputFields = 4;
}
我想获取ModuleName的值:“ FilmMusic”和“ MovieStaffInfo”。
使用该值,在用户输入主表单之前,我可以向主表单添加一个新的UI(用于FilmMusic Module的UI和用于MovieStaff的另一个UI)。
以下是我使用的代码(最参考我上面提到的情况):
public void detectTotalNumberOfSector()
{
IEnumerable<InputModule> exporters = typeof(InputModule).Assembly.GetTypes().Where(t => t.IsSubclassOf(typeof(InputModule)) && !t.IsAbstract).Select(t => (InputModule)Activator.CreateInstance(t));
foreach (var item in exporters)
{
Console.WriteLine(item.ModuleName);
}
}
我得到的输出为“ null,null”
然后我在foreach循环中添加了这些代码:
FieldInfo info = item.GetType().GetField("ModuleName");
Console.WriteLine(info.GetValue(item));
我有想要的“ FilmMusic,MovieStaffInfo”。
我有点困惑,出口商集合中的元素是什么?
首先,我猜测item
是类Module1
,Module2
...的实例,因此我可以使用item.ModuleName
来访问{{ 1}}。
实际上,我不能,我必须使用ModuleName
和FieldInfo
来访问字段值,但这也很奇怪,因为使用GetValue
我必须创建一个实例化首先将其作为分配给GetValue
的参数(在我的情况下,GetValue
是类item
,Module1
的实例化。我想)。
那么,集合导出器的项是否是Module1,Module2类的实例?
如果是,为什么使用Module2
时我为空?
感谢您的意见〜
答案 0 :(得分:1)
您已使用ModuleName
关键字(例如new
)定义了new public string ModuleName
。这意味着,如果将指向实例的变量键入为基类,则将无法看到“新”字段。
如果您希望能够看到模块名称,则有两个选择。
摆脱new
关键字。而是将成员声明为替代,例如
public override string ModuleName = "etc.";
使用反射来调用派生类型上的字段,例如
Console.WriteLine
(
item.GetType()
.GetField("ModuleName", BindingFlags.Instance | BindingFlags.Public)
.GetValue(item)
);
另请参阅Difference between new and overrride
我个人建议第一个选项。需要new
关键字是不寻常的。