Какой тип элемента (коллекции) извлекается из метода Activator.CreateInstance? - PullRequest
0 голосов
/ 27 ноября 2018

У меня есть случай, который очень похож на случай ниже:

Получить все унаследованные классы абстрактного класса

У меня есть два класса, которые унаследованыбазовый класс

это мой базовый класс:

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».

Со значением, прежде чем пользователь войдет в основную форму, я мог бы добавить новый пользовательский интерфейс (пользовательский интерфейс для модуля FilmMusic и другой пользовательский интерфейс)для 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 является инстантиация класса Module1, Module2 ..., поэтому я мог бы использовать item.ModuleName для доступа к значению ModuleName.

На самом деле, я не могу, мне нужно использовать FieldInfo и GetValue для доступа к значению поля, но это также странно, потому что, используя GetValue, я должен сначала создать экземпляр какприсваивание параметра GetValue (в моем случае item - это экземпляр класса Module1, Module2 ... я думаю).

Итак, являются ли элементы экспортеров коллекциисоздание экземпляров класса Module1, Module2 или нет?

Если они есть, то почему я получаю нулевое значение при использовании item.ModuleName?

Спасибо за любое мнение ~

1 Ответ

0 голосов
/ 27 ноября 2018

Вы определили 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 необычно.

...