Как динамически создавать общий объект C # с использованием отражения?

В C # у меня есть следующий объект:

public class Item { } public class Task { } public class TaskA : Task { } public class TaskB : Task { } 

Я хочу динамически создавать TaskA или TaskB, используя C # reflection ( Activator.CreateInstance ). Однако я бы не знал тип перед рукой, поэтому мне нужно динамически создавать TaskA на основе строки типа «namespace.TaskA» или «namespace.TaskAB».

Ознакомьтесь с этой статьей и этим простым примером . Быстрый перевод того же самого на ваши classы …

 var d1 = typeof(Task<>); Type[] typeArgs = { typeof(Item) }; var makeme = d1.MakeGenericType(typeArgs); object o = Activator.CreateInstance(makeme); 

За ваше редактирование: в этом случае вы можете сделать это …

 var d1 = Type.GetType("GenericTest.TaskA`1"); // GenericTest was my namespace, add yours Type[] typeArgs = { typeof(Item) }; var makeme = d1.MakeGenericType(typeArgs); object o = Activator.CreateInstance(makeme); 

Чтобы узнать, где я столкнулся с backtick1 для имени родового classа, см. Эту статью .

Примечание. Если ваш универсальный class принимает несколько типов, вы должны включать запятые, когда вы опускаете имена типов, например:

 Type type = typeof(IReadOnlyDictionary<,>); 

Действительно, вы не сможете написать последнюю строку.

Но вы, вероятно, не хотите создавать объект, просто ради его создания или создания. Вероятно, вы захотите вызвать какой-либо метод для своего вновь созданного экземпляра.

Тогда вам понадобится нечто вроде интерфейса:

 public interface ITask { void Process(object o); } public class Task : ITask { void ITask.Process(object o) { if(o is T) // Just to be sure, and maybe throw an exception Process(o as T); } public void Process(T o) { } } 

и назовите его:

 Type d1 = Type.GetType("TaskA"); //or "TaskB" Type[] typeArgs = { typeof(Item) }; Type makeme = d1.MakeGenericType(typeArgs); ITask task = Activator.CreateInstance(makeme) as ITask; // This can be Item, or any type derived from Item task.Process(new Item()); 

В любом случае вы не будете статически приписаны к типу, который вы не знаете заранее («makeme» в этом случае). ITask позволяет вам добраться до вашего целевого типа.

Если это не то, что вы хотите, вы, вероятно, должны быть немного более конкретными в том, что вы пытаетесь достичь с этим.

Мне кажется, что последняя строка вашего примера кода должна быть просто:

 Task itsMe = o as Task; 

Или я чего-то не хватает?

Удостоверьтесь, что вы делаете это по уважительной причине, простая функция, подобная приведенной ниже, позволит использовать статическую типизацию и позволяет вашей среде IDE делать такие вещи, как «Найти ссылки» и «Рефакторинг -> Переименовать».

 public Task  factory (String name) { Task  result; if (name.CompareTo ("A") == 0) { result = new TaskA (); } else if (name.CompareTo ("B") == 0) { result = new TaskB (); } return result; } 

Я знаю, что этот вопрос разрешен, но в интересах кого-то еще его читающего; если у вас есть все типы, используемые в качестве строк, вы можете сделать это как один лайнер:

 IYourInterface o = (Activator.CreateInstance(Type.GetType("Namespace.TaskA`1[OtherNamespace.TypeParam]") as IYourInterface); 

Всякий раз, когда я это делал, у меня был интерфейс, который я хотел использовать для последующего использования кода, поэтому я применил созданный экземпляр к интерфейсу.

  • Простой способ получить тип classа-оболочки в Java
  • Как вызвать метод Scala Object с использованием отражения?
  • Как я могу получить значение свойства string через Reflection?
  • Как вызвать общий метод с заданным объектом типа?
  • Библиотеки атрибутов и отражений для C ++?
  • Замена строк в java, аналогично шаблону скорости
  • Является ли строка Java действительно неизменной?
  • Как получить текущее имя свойства через reflection?
  • Во время выполнения найдите все classы в приложении Java, которые расширяют базовый class
  • Вычисление переменной с использованием переменной типа
  • Java: доступ к частному конструктору с параметрами типа
  • Давайте будем гением компьютера.