【问题标题】:Create an instance of a Type, provided as a parameter to a method创建类型的实例,作为方法的参数提供
【发布时间】:2009-11-17 19:19:01
【问题描述】:

要实例化的类:

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

一些伪代码:

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

    instance.foo = "bar";
}

到目前为止,鉴于我想要实现的目标的动态性质,我认为我需要使用反射来完成这项工作。

这是我的成功标准:

  • 创建任意类型的实例
  • 无需调用构造函数即可创建类型实例
  • 访问所有公共属性

我将非常感谢一些有效的示例代码。我对 C# 并不陌生,但我以前从未使用过反射。

【问题讨论】:

    标签: c# generics reflection


    【解决方案1】:

    您基本上需要使用反射。使用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() 的方法。

    【讨论】:

    • Docs 和 Intellisense 对我没有任何帮助。你能给我一些工作代码吗?
    • @Wim: Activator.CreateInstance(T) 在我尝试实例化无参数类时不起作用。有什么想法吗?
    • Activator.CreateInstance(typeof(T)) - 或者简单地说 T obj = new T();
    • @Wim:您的代码似乎忽略了 SetProperty 绑定标志。我得到一个 System.MissingMethodException
    • OK - 我终于测试了它,而不是在 HTML 文本框中输入内容。 ;-)
    【解决方案2】:

    尝试以下方法来实际创建实例。

    Object t = Activator.CreateInstance(t);
    

    但是,如果没有泛型和约束,就不可能静态访问您的示例中显示的成员。

    您可以通过以下方式做到这一点

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

    【讨论】:

    • 那就是:T obj = Activator.CreateInstance(); ;-)
    • 应该是T ins = Activator.CreateInstance();
    • @Wim,贡萨洛,谢谢。修复它以使用非泛型 CreateInstance 方法。
    • 不错的解决方案,虽然它似乎破坏了使用泛型的对象,然后将其限制为单一类型。
    【解决方案3】:

    既然你有你想要实例化的类型,你可以使用一个通用的帮助方法:

    公共静态 T New() 其中 T : new() { 返回新的 T(); }

    否则,如果您要在其他地方提取类型(例如动态加载的程序集)并且您无法直接访问该类型(它是某种元编程或反射数据),您应该使用反射。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-07
      • 2018-11-23
      • 1970-01-01
      • 2012-07-05
      相关资源
      最近更新 更多