使用 Activator.CreateInstance 方法检索的(集合的)元素的类型是什么?
What is the type of element (of a collection) which retrieve from using Activator.CreateInstance method?
我有一个案例和下面的案例很相似:
Get all inherited classes of an abstract class
我有两个 classes 继承了一个基数 class
这是我的基地class:
public abstract class InputModule
{
public string ModuleName;
public int NumberOfInputFields;
}
这是第一个继承class:
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(UI 用于 FilmMusic 模块,另一个 UI 用于 MovieStaff)。
下面是我用过的代码(大部分是指我上面提到的案例):
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
是class Module1
, Module2
...的一个实例,所以我可以用item.ModuleName
来访问 ModuleName
的值。
其实我不能,我必须使用FieldInfo
和GetValue
来访问字段值,但也很奇怪,因为使用GetValue
我必须创建首先作为参数分配给 GetValue
的实例化(在我的例子中,item
是 class Module1
,Module2
的实例化......我猜) .
那么,集合导出器的项目是否是class模块1、模块2的实例?
如果是,为什么我在使用 item.ModuleName
时得到 null?
谢谢大家的意见~
您已经使用 new
关键字定义了 ModuleName
(例如 new public string ModuleName
)。这意味着如果指向实例的变量被键入为基础 class,它将无法看到 "new" 字段。
如果您希望能够看到模块名称,您有两个选择。
删除 new
关键字。相反,将该成员声明为覆盖,例如
public override string ModuleName = "etc.";
使用反射调用派生类型上的字段,例如
Console.WriteLine
(
item.GetType()
.GetField("ModuleName", BindingFlags.Instance | BindingFlags.Public)
.GetValue(item)
);
另见 Difference between new and overrride
个人推荐第一种。需要 new
关键字是不常见的。
我有一个案例和下面的案例很相似:
Get all inherited classes of an abstract class
我有两个 classes 继承了一个基数 class
这是我的基地class:
public abstract class InputModule
{
public string ModuleName;
public int NumberOfInputFields;
}
这是第一个继承class:
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(UI 用于 FilmMusic 模块,另一个 UI 用于 MovieStaff)。
下面是我用过的代码(大部分是指我上面提到的案例):
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
是class Module1
, Module2
...的一个实例,所以我可以用item.ModuleName
来访问 ModuleName
的值。
其实我不能,我必须使用FieldInfo
和GetValue
来访问字段值,但也很奇怪,因为使用GetValue
我必须创建首先作为参数分配给 GetValue
的实例化(在我的例子中,item
是 class Module1
,Module2
的实例化......我猜) .
那么,集合导出器的项目是否是class模块1、模块2的实例?
如果是,为什么我在使用 item.ModuleName
时得到 null?
谢谢大家的意见~
您已经使用 new
关键字定义了 ModuleName
(例如 new public string ModuleName
)。这意味着如果指向实例的变量被键入为基础 class,它将无法看到 "new" 字段。
如果您希望能够看到模块名称,您有两个选择。
删除
new
关键字。相反,将该成员声明为覆盖,例如public override string ModuleName = "etc.";
使用反射调用派生类型上的字段,例如
Console.WriteLine ( item.GetType() .GetField("ModuleName", BindingFlags.Instance | BindingFlags.Public) .GetValue(item) );
另见 Difference between new and overrride
个人推荐第一种。需要 new
关键字是不常见的。