C#泛型继承和协方差

时间:2013-01-10 07:35:23

标签: c# generics

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

像这样:

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

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

除非最好的解决方法是什么?接口是非通用的?

2 个答案:

答案 0 :(得分:3)

该行:

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

(评论)适用于out方差;但是,DoSomething(ItemType)需要in方差;因此,该类型既不是in也不是out:variance 不适用于此

通常处理的方式是使用通用的非泛型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)
    {
        //...
    }
}

然后有效:

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

答案 1 :(得分:0)

值类型始终装箱为object类型。这将强制任何盒装值类型的集合为Collection<object>,这实际上并不是类型安全的(没有人阻止您添加例如string,然后)。类型安全性是通用类型的最大优势之一。所以如果可能的话,我建议删除class约束。

BTW:您仍然可以将这些通用接口(没有class约束)分配给它们的非通用版本:
IList l = new List<int>();