ICollection的< T>不是协变? [英] ICollection<T> not Covariant?
问题描述
这样做的目的是要同步两个集合,发送器侧和放大器;接收端,包含图形边缘,这样有事时(删除边,边加等),双方都通知。
The purpose of this is to synchronize two collections, sender-side & receiver-side, containing a graph edge, so that when something happens (remove edge, add edge, etc) both sides are notified.
要做到这一点,(背)的集合引用被包含在集合中的元素
To do so, (back-)references to the collections were included in the element in collections
class EdgeBase {
EdgeBase(ICollection<EdgeBase> rCol, ICollection<EdgeBase> sCol)
{ RecvCol=rCol; SendCol=sCol; }
ICollection<EdgeBase> RecvCol;
ICollection<EdgeBase> SendCol;
public virtual void Disconnect() // Synchronized deletion
{ RecvCol.Remove(this); SendCol.Remove(this); }
}
class Edge : EdgeBase {
Edge(ICollection<EdgeBase> rCol, ICollection<EdgeBase> sCol)
: base(rCol, sCol) {}
int Weight;
}
删除(断开)是确定的,但创作过程中出现的问题:
Deletion (Disconnect) was ok , but the problem occurred during creation:
HashSet<Edge> receiverSet, senderSet;
var edge = new Edge(receiverSet, senderSet); // Can't convert Edge to EdgeBase!
虽然边缘
是<$ C派生$ C> EdgeBase ,这是非法的。
(问题是边缘
一部分,而不是的HashSet<>
部分)
Although Edge
is derived from EdgeBase
, this is illegal.
(The problem is Edge
part, not HashSet<>
part.)
写数百行后,我发现了的ICollection<>
不是协变的是的IEnumerable<>
After writing hundreds of lines I found out ICollection<>
is not covariant as is IEnumerable<>
.
可能是什么解决办法
编辑:
如果我写了上面,而不是打破的C#的协方差规则,它会一直像这样的代码:
If I wrote the code above while not breaking the C#'s covariance rules it would have been like this:
public class EdgeBase<T, U>
where T : ICollection<U<T>> // illegal
where U : EdgeBase<T, U> // legal, but introduces self-reference
{
public EdgeBase(T recvCol, T sendCol) {...}
protected T ReceiverCollection;
protected T SenderCollection;
public virtual void Disconnect() {...}
}
不过,这是非法的; U不能与正式参数T使用。
But this is illegal; 'U' can't be used with formal parameter T.
推荐答案
的埃里克利珀说,C#只支持类型安全的协变和逆变。如果你会想到它,使的ICollection
协不是类型安全的。
Eric Lippert said that C# will only support type-safe covariance and contravariance. If you would think of it, making ICollection
covariant is not type-safe.
让我们说你有
ICollection<Dog> dogList = new List<Dog>();
ICollection<Mammal> mammalList = dogList; //illegal but for the sake of showing, do it
mammalList.Add(new Cat());
您 mammalList
(这实际上是一个 dogList
)现在会那么包含猫
。
Your mammalList
(which is actually a dogList
) would now then contain a Cat
.
的IEnumerable
是协变的,因为你不能添加
将其......你只能从中读取 - 这,反过来,保留类型安全
IEnumerable
is covariant because you cannot Add
to it... you can only read from it -- which, in turn, preserves type-safety.
这篇关于ICollection的< T>不是协变?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!