0

我有一个案例和下面的案例非常相似:</p>

获取一个抽象类的所有继承类

我有两个继承到基类的类

这是我的基类:

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”。

我有点困惑,exporters 集合里面的元素是什么?

起初,我猜item是 class 的实例化Module1Module2...,因此我可以item.ModuleName用来访问ModuleName.

实际上,我不能,我必须使用FieldInfoandGetValue来访问字段值,但这也很奇怪,因为使用GetValue我必须首先创建一个实例化作为分配给的参数GetValue(在我的情况下,item是 class 的实例化Module1Module2... 我猜)。

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

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

谢谢大家的意见~

4

1 回答 1

1

您已经ModuleName使用new关键字(例如new public string ModuleName)进行了定义。这意味着如果指向实例的变量被键入为基类,它将无法看到“新”字段。

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

  1. 摆脱new关键字。相反,将成员声明为覆盖,例如

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

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

另请参见new 和 overrride 之间的区别

我个人推荐第一个选项。需要new关键字是不寻常的。

于 2018-11-27T07:23:36.160 回答