Как создать тип значения или объект строкового типа во время выполнения, используя Reflection - PullRequest
1 голос
/ 28 июня 2010

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

  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, который также не работал.

Ответы [ 3 ]

8 голосов
/ 28 июня 2010

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

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

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

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

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

1 голос
/ 28 июня 2010

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

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

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

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

0 голосов
/ 28 июня 2010

Тип int не имеет конструкторов .

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

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

...