2010-06-28 3 views
1

Наверное, просто, но не мог понять. Я загружаю сборку во время выполнения и просматриваю некоторые классы и создаю элементы управления ввода для своих свойств. Чтобы создать экземпляр объекта во время выполнения, я использую:Как создать тип значения или объект типа строки во время выполнения с использованием Reflection

object o = PropertyType.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, Type.EmptyTypes,null).Invoke(null); 

и он отлично подходит для классов. Когда тип является массивом, я использую

object o = PropertyType.Type.GetConstructor(new Type[] { typeof(int) }).Invoke(new object[] { 0 }); 

который также отлично работает. Но когда дело доходит до типа строк или типов значений GetConstructor.Invoke не работает. Я также попробовал Activator.CreateInstance, который также не работал.

ответ

8

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

Activator.CreateInstance должен работать нормально для типов реальной стоимости, хотя:

object o = Activator.CreateInstance(typeof(int)); 
Console.WriteLine(o); // Prints 0 

Это всегда будет давать значение по умолчанию для любого типа значения.

Теперь вы спрашиваете о строках - какую строку вы ожидаете создать? Значение по умолчанию для типа string равно null, но вместо этого вы хотите использовать пустую строку? Если это так, вам понадобится специальный код для этого кода.

+0

Спасибо, Джон, я отредактировал мой вопрос, не хотел сказать, что строка - это тип значения ... Итак, как насчет создания строки? –

+0

@Erkan: Я отредактировал свой ответ. Какую строку вы хотите создать?Если вы выберете конструктор, который на самом деле существует, вы можете, конечно, вызвать его с отражением - но, конечно, вам нужно будет указать значения для параметров ... –

+0

просто хотите создать динамическое свойство класса, которое имеет тип string, но Я не хочу нулевого значения в созданном объекте. Поэтому, я думаю, мне нужно сделать специальный случай для свойств типа строки в классе. Однако неясно, как создать экземпляр объекта из свойства класса string. Поскольку я буду делать специальный случай: if (property.PropertyType == typeof (string)) object o = ""; быть достаточным? –

0

int тип doesn't have any constructors.

Код, который вы пишете, зависит от его типа; обычно вы должны писать код специального кода для string, int и других примитивных типов.

Ваш код: содержит 0; как вы решаете, какие значения передаются конструкторам?

0

Если вы хотите создать экземпляр произвольных объектов с определенными значениями, одно можно проверить, если есть TypeConverter, который поддерживает преобразование экземпляра (со значением, которое вы хотите сопоставить) в InstanceDescriptor. Я не совсем уверен, что вы делаете (ваш пример предполагает, что вы пытаетесь создать экземпляры по умолчанию для разных объектов), но просто подумал, что упомянул об этом, если это будет актуально. Я использую это в Emit-коде, чтобы испускать произвольные постоянные значения в стек через IL. Вот фрагмент кода, который получает InstanceDescriptor:

 var converter = TypeDescriptor.GetConverter(value); 
     if (converter.CanConvertTo(typeof (InstanceDescriptor))) 
     { 
      var desc = (InstanceDescriptor) converter.ConvertTo(value, typeof (InstanceDescriptor)); 
     } 

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

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