代码之家  ›  专栏  ›  技术社区  ›  Anthony Gatlin

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

  •  0
  • Anthony Gatlin  · 技术社区  · 7 年前

    我有一个专门的泛型集合类,它将用于保存许多不同类型对象的集合。创建集合后,我需要实例化集合的项。我有最宝贵的时间让这个工作。一定有一个简单的解决方案我错过了。

    下面是一个示例类,它说明了我要做什么以及遇到的警告/错误。

    // 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.2beta和.netstandard2.0。

    1 回复  |  直到 7 年前
        1
  •  2
  •   vc 74    7 年前

    好像 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();
    
        2
  •  1
  •   Flydog57    7 年前

    这将编译:

    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 部分。

    推荐文章