c# – ICollection不协变?
发布时间:2020-12-15 04:15:13 所属栏目:百科 来源:网络整理
导读:这样做的目的是同步两个集合,发送方和接收方,包含一个图形边缘,这样当发生某些事情(删除边缘,添加边缘等)时,通知双方. 为了做到这一点,对集合的(back-)引用被包含在集合中的元素中 class EdgeBase { EdgeBase(ICollectionEdgeBase rCol,ICollectionEdgeBase
这样做的目的是同步两个集合,发送方和接收方,包含一个图形边缘,这样当发生某些事情(删除边缘,添加边缘等)时,通知双方.
为了做到这一点,对集合的(back-)引用被包含在集合中的元素中 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; } 删除(断开连接)是确定,但问题发生在创建期间: HashSet<Edge> receiverSet,senderSet; var edge = new Edge(receiverSet,senderSet); // Can't convert Edge to EdgeBase! 虽然Edge来自EdgeBase,但这是非法的. 写了数百行后,我发现ICollection<>不像IEnumerable<>是协变的. 什么可以解决办法? 编辑: 如果我在上面写代码,而不是打破C#的协方差规则,那就是这样的: 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一起使用. 解决方法
Eric Lippert said that C# will only support type-safe covariance and contravariance.如果你想到它,使ICollection协变不是类型安全的.
让我们说你有 ICollection<Dog> dogList = new List<Dog>(); ICollection<Mammal> mammalList = dogList; //illegal but for the sake of showing,do it mammalList.Add(new Cat()); 你的哺乳动物列表(实际上是一个dogList)现在将包含一只猫. IEnumerable是协变的,因为你不能添加到它…你只能从它读取 – 反过来保留类型安全. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |