2009-11-17 4 views
2

Класс для создания экземпляра:Создать экземпляр типа, при условии, в качестве параметра метода

public class InstantiateMe 
{ 
    public String foo 
    { 
     get; 
     set; 
    } 
} 

Некоторые псевдо-код:

public void CreateInstanceOf(Type t) 
{ 
    var instance = new t(); 

    instance.foo = "bar"; 
} 

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

Вот мои критерии успеха годы:

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

Я бы очень оцените некоторый рабочий пример-код. Я не новичок в C#, но я никогда не работал с размышлениями раньше.

ответ

4

Вам в основном нужно использовать Reflection. Используйте Activator.CreateInstance() построить свой тип, а затем вызвать InvokeMember() от типа, чтобы установить свойство:

public void CreateInstanceOfType(Type t) 
{ 
    var instance = Activator.CreateInstance(t); // create instance 

    // set property on the instance 
    t.InvokeMember(
     "foo", // property name 
     BindingFlags.SetProperty, 
     null, 
     obj, 
     new Object[] { "bar" } // property value 
    ); 
} 

Чтобы получить доступ ко всем свойствам общего типа и установить/получить их, вы можете использовать GetProperties(), который возвращает PropertyInfo коллекцию , которые вы можете перебирать:

foreach (PropertyInfo property in type.GetProperties()) 
{ 
    property.GetValue() // get property 
    property.SetValue() // set property 
} 

Также см the documentation новые способы использования InvokeMember().

+0

Docs и Intellisense ничего не делают для меня. Не могли бы вы предоставить мне какой-нибудь рабочий код? – roosteronacid

+0

Отредактировано соответственно. –

+0

@Wim: 'Activator.CreateInstance (T)' не работает, когда я пытаюсь создать экземпляр класса без параметров. Есть идеи? – roosteronacid

4

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

Object t = Activator.CreateInstance(t); 

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

Вы можете сделать это следующим хотя

public void CreateInstanceOf<T>() where T : InstantiateMe, new() 
{ 
    T i = new T(); 
    i.foo = "bar"; 
} 
+0

Это будет: T obj = Activator.CreateInstance (); ;-) –

+0

Должно быть T ins = Activator.CreateInstance (); – Gonzalo

+0

@Wim, Гонсало, спасибо. Исправлено использование неосновного метода CreateInstance. – JaredPar

0

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

 
public static T New() where T : new() 
{ 
    return new T(); 
} 

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

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