2013-01-10 47 views
-5

这是我原来的线程: C# generic inheritance and covarianceC#泛型继承和协方差部分2

在刚刚我只读接口,我想的传承工作。

public delegate Boolean EnumerateItemsDelegate<out ItemType>(ItemType item); 

public interface IReadOnlyCollection<out ItemType> 
{ 
    Boolean ContainsItem(ItemType item); 
    Array CopyToArray(); 
    void EnumerateItems(EnumerateItemsDelegate<ItemType> enumerateDelegate); 

    UInt32 Count { get; } 
    UInt32 Capacity { get; } 
} 

像这样,除非它编译:-P

这是我想什么去上班:

IReadOnlyCollection<String> s; 
IReadOnlyCollection<Object> o = s; 
+0

顺便提一句,'ItemType'应该叫做'T'。 – SLaks

+0

而不是让'CopyToArray'返回'Array',让它返回'ItemType []',这样它的强类型。 – Servy

+2

这个问题似乎没有任何问题。 “我想要继承工作”不是一个问题。如果你想要一个答案,将其重写为一个问题。编译器是正确的;此代码不是类型安全的。 –

回答

5

似乎没有要在这个问题上的任何问题,所以我会提出几个问题来回答。

什么是协变转换?

让我们假设我们有一些类型的FruitAppleBanana具有明显的关系; Apple是一种Fruit,依此类推。

协变转换是其中类型参数的可转换性意味着泛型类型的可转换性的转换。如果Apple可转换为Fruit,并Bowl<Apple>可转换为Bowl<Fruit>,然后Bowl<T>在T.


什么是逆变转换协变?

甲逆变转换是一种协变转换该反转方向,而不是保存。如果Eater<Fruit>可转换为Eater<Apple>然后Eater<T>是T.


逆变我要怎样接口或委托为在其类型参数的协变或逆变?

协变类型参数标记为out,逆变类型参数标记为in

这是为了助记符:协变接口通常在输出位置出现类型参数,并且反向接口有类型参数出现在输入位置。


String可转换为Object。我怎样才能让IReadOnlyCollection<String>兑换成IReadOnlyCollection<Object>

请在T.马克它outIReadOnlyCollection<T>协变。


考虑下面的代码:

delegate void Action<in T>(T t); 
interface IFoo<in X> 
{ 
    void M(Action<X> action); 
} 

为什么编译器说,这是不是有效?

因为它是无效的。让我们看看为什么。

class Foo : IFoo<Fruit> 
{ 
    public void M(Action<Fruit> action) 
    { 
    action(new Apple()); // An apple is a fruit. 
    } 
} 
... 
IFoo<Fruit> iff = new Foo(); 
IFoo<Banana> ifb = iff; // Contravariant! 
ifb.M(banana => { banana.Peel(); }); 

按照逻辑。这个程序通过一个苹果作为Banana.Peel()的“这个”,这显然是错误的。

编译器知道这可能发生,因此不允许首先声明接口。


我应该怎么做,如果我有变化的问题吗?

您应该先阅读我关于该功能设计和实现的文章。从底部开始;它们列出以相反的顺序为:

http://blogs.msdn.com/b/ericlippert/archive/tags/covariance+and+contravariance/

如果您仍然有问题,那么你应该在这里张贴问题,实际上包含的问题,而不是让人们猜测什么真正的问题是。

+0

你是对的我真的想出来,现在只是告诉编译器,ContainsItem不关心类型,只要它是一个引用类型... –

+0

@RyanBrown看到我上面的评论。要告诉编译器你不关心'ContainsItem'方法的参数类型,使它成为一个新的泛型类型,它继承自'ItemType'如下:'bool ContainsItem (T item)where T :ItemType;'。 – jam40jeff