c#泛型继承和协方差第2部分
本文关键字:方差第 2部 泛型 继承 | 更新日期: 2023-09-27 17:51:12
这是我的原始线程:c#泛型继承和协方差
只在我的只读接口上,我希望继承工作。
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;
这个问题似乎没有什么问题,所以我将编几个问题来回答。
什么是协变转换?
假设有几种类型Fruit
、Apple
和Banana
,它们之间的关系很明显;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>
?
使IReadOnlyCollection<T>
在t中协变,标记为out
。
考虑以下代码:
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()
的" This "传递,这显然是错误的。
编译器知道这种情况可能发生,因此一开始就不允许声明接口。
如果我有更多关于方差的问题该怎么办?
您应该先阅读我关于该特性的设计和实现的文章。从底层开始;它们按时间倒序排列:
http://blogs.msdn.com/b/ericlippert/archive/tags/covariance +和+抗变性/
如果你仍然有问题,那么你应该在这里发布包含问题的问题,而不是让人们猜测问题的真正内容。