【问题标题】:Create intance of any C# class by generic way通过通用方式创建任何 C# 类的实例
【发布时间】:2009-12-16 11:04:33
【问题描述】:

我想使用泛型创建任何类的实例。 这可能吗?

我试过了,但没有用:

public class blabla 
{
    public void bla();
}
public class Foo<T>
{
    Dictionary<string, Func<object>> factory;

    public Foo() => factory = new Dictionary<string, Func<object>>();
    public WrapMe(string key) => factory.Add(key, () => new T());
}

...

var foo = new Foo<blabla>();
foo.Wrapme("myBlabla");

var instance = foo.factory["myBlabla"];
instance.Bla();

【问题讨论】:

    标签: c# generics


    【解决方案1】:

    有两种方法可以解决这个问题:

    变体 1:将 where T : new() 添加到您的类定义中:

    public class Foo<T> where T : new()
    {
        ...
    }
    

    更多详情请查看the new() constraint的描述。


    变体 2:将 lambda () =&gt; new T() 作为参数传递给构造函数,将其存储在 Func&lt;T&gt; 字段中并在 WrapMe 中使用。

    更多详情请见this blog post

    【讨论】:

      【解决方案2】:

      你只需要一个方法:

      private static T InstantiateInstance<T>() where T : new() => new T();
      

      【讨论】:

        【解决方案3】:

        您可以使用Activator.CreateInstance&lt;T&gt;()

        【讨论】:

        • 是的,比我的方法好。
        • @grenade - 与您的方法相同。唯一的区别是-您的方法将在编译时失败,Diego 的方法将在运行时失败
        • @Krzysztof Koźmic,想详细说明一下吗?这两种方法都可以在这里编译并运行良好。
        • 如果你不添加 new() 并使用显式调用 Activator,当你传递一个没有默认 .ctor 的类型时调用将失败,这就是失败的部分。当您添加 new() 约束,然后调用 var t = new T() 时,编译器将发出对 Activator.CreateInstance() 的调用,这就是“相同”部分。
        【解决方案4】:

        【讨论】:

          【解决方案5】:

          在声明 Foo 时需要使用新的约束。这仅适用于具有不带参数的构造函数的类型 - 这在您的情况下很好。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2014-02-02
            • 1970-01-01
            • 2016-09-14
            • 1970-01-01
            • 2016-01-09
            • 2018-02-27
            • 2014-05-29
            相关资源
            最近更新 更多