如何使用Reflection在运行时创建值类型或字符串类型对象

时间:2010-06-28 15:28:26

标签: c# reflection object instantiation

可能简单但无法弄清楚。我在运行时加载程序集并浏览一些类并为其属性生成输入控件。要在运行时创建对象的实例,我使用:

  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 个答案:

答案 0 :(得分:8)

您遇到的是值类型实际上没有无参数构造函数。 C#使它看起来像一样,但它们不在CLR级别。

Activator.CreateInstance应该适用于实际值类型:

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

这将始终为任何值类型提供默认值。

现在,你问的是字符串 - 你期望创建什么字符串? string类型的默认值为null - 但是您想要空字符串吗?如果是这样,你需要特殊情况下的代码。

答案 1 :(得分:1)

如果您希望能够使用特定值实例化任意对象,您可以检查的一件事是,是否存在支持将实例(具有您想要匹配的值)转换为InstanceDescriptor的TypeConverter。我不完全确定你在做什么(你的例子暗示你正在尝试创建不同对象的'默认'实例),但我想如果它是相关的话我会提到它。我在Emit代码中使用它来通过IL向堆栈发出任意常量值。这是获取InstanceDescriptor的片段:

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

描述符指定构造实例的方法,可以调用构造函数,调用静态方法,访问静态属性或访问静态字段。它还指定构造是否完全设置类型的值以匹配原始实例;如果没有,你需要做额外的反射和属性设置。

这是WinForms Designer在为窗体上的控件生成代码隐藏时使用的机制,因此它支持显示为可从设计器访问的控件属性的常见类型。

答案 2 :(得分:0)

int类型doesn't have any constructors

您编写的代码将取决于属性的类型;通常,您要为stringint和其他原始类型编写特例代码。

上面的代码包含文字0;你如何决定传递给构造函数的值?