Cap*_*and 0 c# generics list add covariance
我有一个通用的基类,其他泛型类继承它:
public class B<T> {
private List<T> parent;
public bool IsInParent() { return parent.Contains(this); }
public void Attach() { parent.Add(this); }
}
Run Code Online (Sandbox Code Playgroud)
这两个this错误"无法转换B<T>为T.我明白这是因为this可能是其他T(协方差)的事实,因此不会进入a List<T>.我理解的很多.
如果我声明T继承自B<T>第一个没有错误,this但Add的错误this仍然存在.
public class B<T> where T : B<T> { ..... ]
Run Code Online (Sandbox Code Playgroud)
现在肯定如果每一个都T继承B<T>,那么每一个B<T>都是一个T,因此应该进入一个List<T>.
我究竟做错了什么?
这两个给出了错误"无法转换
B<T>为T.我明白这是因为this可能是其他的事情T(协方差),因此不会进入List<T>.
我不认为你理解它.
第一种:this属于类型B<T>.想象一下,而不是抽象,B<T>我们使它更具体:
class Comparer<T> // I can compare two things of type T.
{
....
Run Code Online (Sandbox Code Playgroud)
this里面Comparer<T>将是类型Comparer<T>.如果你有List<T>,你可以把一个T放入列表.假设T是Apple. this可以比较两个苹果.该List<T>可包含两个苹果.但是List<T> 不能包含两个苹果比较器,因为那不是它的类型!
其次,你不明白"协方差"这个词是什么意思.我不知道你认为这意味着什么,但我的猜测是你认为"协方差"意味着"赋值兼容性".这通常是人们认为"协方差"意味着它们的含义是错误的.
"作业兼容性"是该类型的值的属性Apple可以进入类型的变量Fruit,因为Apple是分配兼容具有给存储Fruit. 这不是协方差.
协方差是通用类型保留赋值兼容性关系的属性.
那就是:一个Apple可以进入一个类型的变量Fruit,因此IEnumerable<Apple>可以进入一个类型的变量IEnumerable<Fruit>.分配兼容性的关系被保留,因为类型通过使它们通用而变化,因此IEnumerable<T>是共变体 ; 事物在同一个方向上变化.
如果我声明
T继承自B<T>第一个没有错误,但Addthis遗骸的错误.
首先:不要这样做.这是一个糟糕的模式.它是C++模式的一种变体,称为"奇怪的重复模板模式".我已经看到它在C#中使用了很多次,而且几乎总是使用错误的.躲开它.它使您的类型变得复杂,难以使用,难以理解,并且它使您认为您对C#不支持的类型有约束.
现在肯定如果每一个都
T继承B<T>,那么每一个B<T>都是一个T,因此应该进入一个List<T>.
现在你也许开始明白为什么这种模式太可怕了.它让你相信完全疯狂的虚假事物,因为它太混乱了!
让我们再次让你的句子不那么混乱.我们将代替T与Apple和B<T>与Fruit我们具有:
现在肯定的是,如果每个苹果都是一种水果,那么每个水果都是一个苹果,因此应该进入一碗苹果".
你的结论是,苹果是水果,因此所有的水果都是苹果,所以你可以把香蕉放入一碗苹果中,它仍然是一碗苹果.显然这是荒谬的.
我究竟做错了什么?
您正在构建非常复杂的泛型类型,以至于无法正确理解它们.这意味着使用您的代码的人也无法理解它们.找到一种更简单的方法来解决您的问题.