在C#中实例化泛型类型的实例

时间:2019-03-15 20:53:59

标签: c# .net generics

我有一个专门的通用集合类,它将用于保存许多不同类型的对象的集合。创建集合后,我需要实例化集合的项目。我有最迫切的时间让它工作。我必须缺少一个简单的解决方案。

这是一个示例类,用于说明我正在尝试执行的操作以及遇到的警告/错误。

// Note: T may either a string or other reference type that supports IEnumerable. 
public class Foo<T>
{
    private List<T> fooBarList = new List<T>();

    public Foo()
    {
        Bar1<T>();
        Bar2<T>();
        Bar3<T>();
    }

    public void Bar1<T>()
    {
        // Error Message: Argument 1 cannot convert from 'T...' to 'T...'
        T t = default;
        fooBarList.Add(t);
    }

    public void Bar2<T>() where T : IEnumerable, new()
    {
        // Error Message: T must be a non-abstract type with public
        // parameterless constructor in order to use it as a parameter 'T'
        // in the generic type or method 'Foo<T>.Bar2<T>()

        fooBarList.Add(new T());
    }

    public void Bar3<T>() where T : IEnumerable, new()
    {
        // Error Message: Argument 1 cannot convert from 'T...' to 'T...'
        T t = Activator.CreateInstance<T>();
        fooBarList.Add(t);
    }
}

旁注:此特定代码在我的应用程序中对性能至关重要的部分中-您知道,3%的Donald Knuth谈到需要进行实际优化。这确实需要快速,因为每个应用程序执行将被调用数百万次。如果有其他选择,我对使用反射(例如此处的Activator.CreateInstance())一点也不热心。 (就目前而言,即使对于我来说似乎也不起作用。)我宁愿让编译器在编译时解析数据类型。

下面的链接中已经回答了这个问题,但是似乎没有一种方法对我有用。我想念什么?

In C#, how to instantiate a passed generic type inside a method?

仅供参考,我在运行Visual Studio 2019企业预览版的Windows 10计算机上使用.NET Core 2.2 Beta和.NET Standard 2.0。

2 个答案:

答案 0 :(得分:2)

List<T>似乎已经拥有您所需的全部内容,只是创建新实例并添加它的方法,可以将其添加为扩展方法:

public static ICollectionExtensions
{
    public static AddNew<T>(this ICollection<T> collection)
        where T : new()
    {
        var newItem = new T();
        collection.Add(newItem);
    }

    ...
} 

可以这样使用:

var list = new List<int>();
list.AddNew();

答案 1 :(得分:1)

它将编译:

public class Foo<T> where T : IEnumerable, new()
{
    private List<T> fooBarList = new List<T>();

    public Foo()
    {
        Bar1();
        Bar2();
        Bar3();
    }

    public void Bar1()
    {
        T t = default(T);
        fooBarList.Add(t);
    }

    public void Bar2()
    {
        fooBarList.Add(new T());
    }

    public void Bar3() 
    {
        T t = Activator.CreateInstance<T>();
        fooBarList.Add(t);
    }
}

请注意,T的唯一声明是在类级别上的,<T>部分和where部分都是如此。