Создайте экземпляр унаследованного класса из конструктора абстрактного базового класса

#c# #reflection #constructor #abstract-class

#c# #отражение #конструктор #абстрактный класс

Вопрос:

Используя отражение, возможно ли создать экземпляр типа, который наследуется от абстрактного базового класса, используя конструктор абстрактного базового класса? То есть, без наличия у наследующего класса собственного конструктора? Примерно так, как показано ниже, но это выдает ошибку, потому что вы, конечно, не можете создать экземпляр абстрактного класса:

 abstract class PersonBase
{
     string Name;

     public PersonBase(string _name) { Name = _name; }
}

class Person : PersonBase
{

}

public static T GetPerson<T>(string name) where T : PersonBase, new()
{
   ConstructorInfo info = typeof(T).BaseType.GetConstructor(new Type[] 
                                                              { typeof(string) });

   object result = info.Invoke(new object[] { name }); 

   return (T)resu<    
}
  

Вы можете выполнить эту работу, выполнив new T { (назначить свойства здесь) } но, конечно, это не конструктор, и свойства должны быть общедоступными и т.д.

Комментарии:

1. Обычно это рассматривается как простой случай для фабричного метода .

Ответ №1:

Единственное место, где законно вызывать конструктор абстрактного класса — независимо от того, путем отражения или нет — находится внутри конструктора производного класса. Итак, нет — как вы говорите, вы бы создали экземпляр абстрактного типа вместо конкретного типа. Представьте, если бы у абстрактного класса был абстрактный метод, и вы вызвали бы его для того, что возвращает конструктор, — что бы это дало?

Если вы можете предоставить нам больше информации о том, чего вы пытаетесь достичь, возможно, мы сможем вам больше помочь.

(Ваш текущий пример даже не будет скомпилирован, поскольку у Person конструктора по умолчанию нет конструктора базового класса без параметров для вызова.)

Комментарии:

1. Я создаю абстрактный неизменяемый тип с членом, доступным только для чтения. Я хочу, чтобы этот универсальный метод ‘Get’ мог получать экземпляр любого класса, производного от этого абстрактного типа, используя базовый конструктор. Поскольку элемент является неизменяемым, он должен быть назначен в конструкторе. Не хотите, чтобы наследуемые типы вообще имели конструктор, если это возможно. Но я пойду другим путем.

2. @Sean: Вы не можете создать тип, у которого нет конструктора, отличного от статического класса (который не может наследоваться ни от чего, кроме object ), и вы не можете создать экземпляр только абстрактного класса.

3. Ну, вы можете создать класс, который имеет только общедоступные свойства, и инициализировать его следующим образом: new Foo { Property1 = x, Property2 = x }. Я предполагаю, что у этого класса все еще есть конструктор без параметров по умолчанию. Я полагаю, я имел в виду отсутствие конструктора, отличного от default. В любом случае свойства, доступные только для чтения, не могут быть инициализированы таким образом.

4. @Sean: Это вызывает конструктор без параметров или, возможно, конструктор с необязательными параметрами. Он все еще вызывает конструктор. Подойдет только конструктор без параметров, но этот конструктор должен был бы вызывать конструктор в вашем базовом классе. Все еще не ясно, почему вы пытаетесь это сделать. Если вы можете представить нам общую картину, мы вполне можем помочь.

5. @Sean: Вам не обязательно публиковать полный код — просто дайте нам представление о более широкой картине, которой вы пытаетесь достичь.