2011-01-14 3 views
0

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

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

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

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

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

AddToList(typeof(Whatever)); 

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

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

+0

«Отражение» в значительной степени определяется как то, что вы пытаетесь сделать ... почему вы пытаетесь это сделать? Откуда берется «Тип»? –

+0

@ Karl see my edit – Earlz

+0

Вы создаете фабрику объектов? Если это так, вас может заинтересовать http://blogs.lessthandot.com/index.php/DesktopDev/MSTech/structuremap-is-way-cool – Rob

ответ

2

Использование Дженерики:

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

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

object t = Activator.CreateInstance(yourTypeVariable); 

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

+1

Фактически активатор является отражением: http://msdn.microsoft.com/ru -us/library/aa310399% 28v = vs.71% 29.aspx – Earlz

+0

Activator.CreateInstance() поддерживает аргументы, он принимает их как объект [] – Rob

+0

Ах, правильно. Я тоже это прочитал. Однако, поскольку перечисление объектов типа всегда возможно, деревья выражений должны работать (вам нужно использовать немного отражения, чтобы получить членские выражения для выражений). – Femaref

2

Другое альтернативное решение - 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()). Это решение существенно сериализует объект и затем десериализует его на объект, поэтому вам не нужно использовать отражение для вызова его конструктора. Но при сериализации/десериализации все еще есть отражение.

+0

+1, но не то, что 'FormatterServices.GetUninitializedObject (typeof (MyClass))' ужасно медленно .. – nawfal

0

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

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

public delegate MyBaseType TypeCreator(); 

... 
public TypeCreator Creator; 

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

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

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

Смежные вопросы