Возможно ли создать новый экземпляр типа без отражения? - PullRequest
0 голосов
/ 14 января 2011

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

Прямо сейчас я делаю это с

object o=MyType.GetConstructors()[0].Invoke(new object[0]);

, который довольно хакерский, а также не будет работать при среднем доверии из-за рефлексии (я думаю). Есть ли лучший способ сделать это без размышлений?

Тип определяется таким образом как часть функции. Мне нужно, чтобы класс создавался "лениво", потому что он не может быть создан в приложении, если он не нужен. Я использую его, например, как

AddToList(typeof(Whatever)); 

Обратите внимание, я открыт для предложений по изменению вызова функции. Мне просто нужно, чтобы объект создавался лениво и для хранения типа (или, тем не менее, для создания объекта типа) в списке.

Я рассматривал лямбды, но я не уверен, что они будут работать здесь.

Ответы [ 3 ]

2 голосов
/ 14 января 2011

Другим альтернативным решением является FormatterServices .

object instance = FormatterServices.GetUninitializedObject(typeof(MyClass));

Обратите внимание, что экземпляр создается без инициализированных полей / свойств, даже если у вас есть

class MyClass
{
   public int i = 99;
   public Object o = new object();
}

instance.i будет 0, а instance.o будет нулевым.Довольно сложно обеспечить решение без отражения (потому что всегда нужно звонить o.GetType()).Это решение по существу сериализует объект, а затем десериализует его в объект, поэтому вам не нужно использовать отражение для вызова его конструктора.Но при сериализации / десериализации все еще есть отражение.

2 голосов
/ 14 января 2011

Использование Generics:

public void Method<T>() where T : class, new()
{
  //code
  T t = new T();
}

Использование Activator (все еще отражение, ме):

object t = Activator.CreateInstance(yourTypeVariable);

Лично я предпочел бы первое решение из-за строгой типизации.Однако вы должны знать, что оба метода допускают только конструкторы без параметров.Если вам нужно передать параметры, вам понадобятся деревья отражений или выражений.

0 голосов
/ 14 января 2011

После дальнейших исследований лямбд, я обнаружил, что они дадут мне гораздо более элегантное решение, в котором не используется отражение

Так что я использовал в своем определении списка

public delegate MyBaseType TypeCreator();

...
public TypeCreator Creator;

и в моем вызове функции, простой и элегантный лямбда:

AddToList(()=>{return new MyType();});

Я думаю, что это немного чище, чем мой метод отражения, потому что он позволяет помещать параметры в конструктор, и несколько других причин за пределамиСфера этого вопроса.(Это хорошо сочетается с моим проектом)

...