c#泛型继承和协方差

本文关键字:方差 继承 泛型 | 更新日期: 2023-09-27 17:51:08

我正在构建一个集合库,我希望所有的泛型集合接口都需要类类型和所有实现它们的集合是任何类型。因此,对于值类型,集合将有两个方法,一个用于值类型,另一个用于装箱。这可能吗?

:

interface ICollection<ItemType> where ItemType : class
{
    void DoSomething(ItemType item);
}
class Collection<ItemType> : ICollection<ItemType>
{
    void DoSomething(Object item);
    void DoSomething(ItemType item);
}

除此之外,最好的解决办法是什么?接口是非通用的?

c#泛型继承和协方差

一行:

ICollection<Object> s = new Collection<String>();

(注释)对out方差有效;然而,DoSomething(ItemType)需要in方差;因此,类型既不是in也不是out:方差不适用于这里

通常的处理方法是使用泛型和非泛型 API。对特定类型感兴趣的人可以使用通用API;对"对象"感兴趣的人可以使用非泛型API。 说明:

interface ICollection
{
    void DoSomething(object item);
}
interface ICollection<ItemType> : ICollection
{
    void DoSomething(ItemType item);
}
class Collection<ItemType> : ICollection<ItemType>
{
    void ICollection.DoSomething(Object item)
    {
        DoSomething((ItemType)item);
    }
    public void DoSomething(ItemType item)
    {
        //...
    }
}

Then this works:

ICollection s = new Collection<String>();
object o = "abcd";
s.DoSomething(o);

值类型总是被装箱为object类型。这将强制任何盒装值类型的集合为Collection<object>,这并不是真正的类型安全(因此,没有人阻止您添加例如string)。类型安全是泛型类型最大的优点之一。所以我建议删除class约束,如果可能的话。

顺便说一句:您仍然可以将这些泛型接口(没有class约束)分配给它们的非泛型版本:
IList l = new List<int>();