将泛型对象添加到 C# 中的泛型列表

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/754341/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 23:54:02  来源:igfitidea点击:

Adding generic object to generic list in C#

c#genericslist

提问by errcw

I have class where the relevant part looks like

我有相关部分看起来像的课程

class C {
    void Method<T>(SomeClass<T> obj) {
        list.Add(obj);
    }
    List<?> list = new List<?>();
}

How should I define the list so that the class compiles?

我应该如何定义列表以便类编译?

I want a list of type List<SomeClass<?>>, that is a list of objects of SomeClasswhere each object can have any type parameter. The Java ?construct allows this; what is the C# equivalent? If no such thing exists, is there a suitable workaround? (A List<object>would do but is terribly ugly.)

我想要一个 typeList<SomeClass<?>>列表,SomeClass即每个对象可以具有任何类型参数的对象列表。Java?构造允许这样做;什么是 C# 等价物?如果不存在这样的东西,是否有合适的解决方法?(AList<object>可以,但非常丑陋。)

采纳答案by Daniel Schaffer

I don't think you can do this in C#... you would have to add the type parameter to the class:

我不认为你可以在 C# 中做到这一点......你必须将类型参数添加到类中:

class C<T> {
    void Method(SomeClass<T> obj) {
        list.Add(obj);
    }
    List<SomeClass<T>> list = new List<SomeClass<T>>();
}

The other option would be to use an interface:

另一种选择是使用接口:

class C {

    void Method<T>(T obj)
         where T : ISomeClass {
        list.Add(obj);
    }
    List<ISomeClass> list = new List<ISomeClass>();
}

回答by Mehrdad Afshari

Unfortunately, there is no direct equivalent in C# 3.0 as generics are invariant. You'll be able to do something like this in a graceful manner using C# 4.0 safe co/contra-variance feature. To workaround it, you could inherit SomeClass<T>from a nongeneric base and create a List<BaseClass>instead. If each instance of the class should hold only one type, you could make the class itself generic and set the type parameter there.

不幸的是,在 C# 3.0 中没有直接的等价物,因为泛型是不变的。您将能够使用 C# 4.0 安全协/反方差功能以优雅的方式执行此类操作。要解决此问题,您可以SomeClass<T>从非泛型基础继承并创建一个List<BaseClass>替代。如果类的每个实例应该只包含一种类型,您可以使类本身成为泛型并在那里设置类型参数。

回答by Reed Copsey

To do what you want, you have two options.

要做你想做的事,你有两个选择。

You can use List<object>, and handle objects. This will not be typesafe, and will have boxing/unboxing issues for value types, but it will work.

您可以使用 List<object> 并处理对象。这不会是类型安全的,并且会出现值类型的装箱/拆箱问题,但它会起作用。

Your other option is to use a generic constraint to limit to a base class or interface, and use a List<Interface>.

您的另一个选择是使用通用约束来限制基类或接口,并使用 List<Interface>。

回答by Dаn

I don't know anything about Java's ?construct, but I think the following most closely preserves your existing syntax while also matching your description.

我对 Java 的?构造一无所知,但我认为以下内容最接近地保留了您现有的语法,同时也与您的描述相匹配。

    class SomeClass<T>
    {
    }

    class C
    {
        void Add<T>(SomeClass<T> item)
        {
            Type type = typeof(SomeClass<T>);
            if (!list.ContainsKey(type))
                list[type] = new List<SomeClass<T>>();
            var l = (List<SomeClass<T>>)list[type];
            l.Add(item);
        }

        public void Method<T>(SomeClass<T> obj)
        {
            Add(obj);
        }
        readonly Dictionary<Type, object> list = new Dictionary<Type, object>();
    }

test it with the following:

使用以下内容对其进行测试:

    class Program
    {
        static void Main(string[] args)
        {
            var c = new C();
            var sc1 = new SomeClass<int>();
            var sc2 = new SomeClass<String>();
            c.Method(sc1);
            c.Method(sc2);
            c.Method(sc1);
            c.Method(sc2);
        }
    }

回答by Gusdor

Personally, I would do this where possible; move the generic parameter from the method, to the class.

就个人而言,我会在可能的情况下这样做;将泛型参数从方法移动到类。

class C<T> {
    void Method(SomeClass<T> obj) {
        list.Add(obj);
    }
    List<?> list = new List<?>();
}

If your generic list is a member, it stands to reason that the class should be constructed with this in mind. It is hard for us to suggest the best pattern without more usage context for the class.

如果您的泛型列表是成员,则应该考虑到这一点来构造类。如果没有更多的类使用上下文,我们很难提出最佳模式。