gpt4 book ai didi

c# - ICollection 不是协变的?

转载 作者:可可西里 更新时间:2023-11-01 08:38:46 25 4
gpt4 key购买 nike

这样做的目的是同步两个集合,发送端和接收端,包含一个图的边,这样当发生某些事情(删除边,添加边等)时,双方都会收到通知。

为此,对集合的(反向)引用包含在集合中的元素中

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;
}

删除(Disconnect)是可以的,但是创建时出现问题:

HashSet<Edge> receiverSet, senderSet;
var edge = new Edge(receiverSet, senderSet); // Can't convert Edge to EdgeBase!

尽管Edge源自 EdgeBase ,这是违法的。(问题是 Edge 部分,而不是 HashSet<> 部分。)

写了几百行之后我发现了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());

你的 mammalList (实际上是一个 dogList )现在将包含一个 Cat .

IEnumerable<T>是协变的,因为你不能 Add到它......你只能从它读取 - 这反过来又保留了类型安全。

关于c# - ICollection<T> 不是协变的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16996626/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com