Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用Activator.CreateInstance方法从中检索的元素(集合)的类型是什么?_C#_.net_Reflection_Createinstance_Fieldinfo - Fatal编程技术网

C# 使用Activator.CreateInstance方法从中检索的元素(集合)的类型是什么?

C# 使用Activator.CreateInstance方法从中检索的元素(集合)的类型是什么?,c#,.net,reflection,createinstance,fieldinfo,C#,.net,Reflection,Createinstance,Fieldinfo,我有一个案例与下面的案例非常相似: 我有两个继承到基类的类 这是我的基类: public abstract class InputModule { public string ModuleName; public int NumberOfInputFields; } 这是第一个固有的课程: public class Module1 : InputModule { new public string ModuleName = "FilmMusic";

我有一个案例与下面的案例非常相似:

我有两个继承到基类的类

这是我的基类:

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的价值:电影音乐和电影TaffInfo

有了这个值,在用户进入主窗体之前,我可以为FilmMusic模块添加一个新的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);   
     } 
}
我已经得到了我想要的电影音乐,电影资讯

我有点困惑,出口商系列中的元素是什么

首先,我猜该项是Module1、Module2…类的实例化,因此我可以使用item.ModuleName访问ModuleName的值

实际上,我不能,我必须使用FieldInfo和GetValue来访问字段值,但这也很奇怪,因为使用GetValue我必须首先创建一个实例化,作为分配给GetValue的参数。在我的例子中,该项是类Module1,Module2的实例化。。。我想是吧

那么,集合导出器的项是否是类Module1、Module2的实例化

如果是,为什么我在使用item.ModuleName时得到null

感谢您的意见~

您已经使用新关键字定义了ModuleName,例如新的公共字符串ModuleName。这意味着,如果指向实例的变量被类型化为基类,它将无法看到新字段

如果希望能够看到模块名称,有两个选项

去掉新的关键字。相反,将成员声明为重写,例如

public override string ModuleName = "etc."; 
使用反射调用派生类型上的字段,例如

Console.WriteLine
(
    item.GetType()
        .GetField("ModuleName", BindingFlags.Instance | BindingFlags.Public)
        .GetValue(item)
);
另见


我个人推荐第一种选择。需要新关键字是不常见的。

为什么您认为您的字段需要新的修改器?我很确定这是他们造成的麻烦。我已经尝试从新的公共字符串ModuleName=FilmMusic和新的公共字符串ModuleName=MovieStaffInfo中删除新的;但输出时仍然为null。这仍然隐藏基类中的原始成员。使用构造函数设置值。重新定义字段意味着现在有两个完整的独立字段:InputModule.ModuleName和Module1.ModuleName。由于解释,这很有帮助。不重新定义字段,只在构造函数中设置其值也是一个选项。谢谢,我明白了。该项实际上是模块1、模块2。。。因此,我可以使用item通过GetValue获取字段ModuleName的值。使用item.ModuleName时得到null的原因,因为它引用基类的ModuleName,并且值为null。
Console.WriteLine
(
    item.GetType()
        .GetField("ModuleName", BindingFlags.Instance | BindingFlags.Public)
        .GetValue(item)
);