如何解决如何在 C# 中对列表列表使用多态性
我在 C# 中将多态性与 int
列表一起使用时遇到问题。我需要“外部”列表才能添加/删除“内部”列表,但“内部”列表不需要更改。所以我考虑使用变量类型ICollection<IEnumerable<int>>
。
现在,我现在知道这有效:
IEnumerable<int> someList = new List<int>(); //Works fine
现在我也知道这有效:
ICollection<int> anotherList = new List<int>(); //Also works fine
然而,我惊讶地发现这会引发编译错误:
ICollection<IEnumerable<int>> listofLists = new List<List<int>>(); //Doesn't compile
不能隐式转换类型
'System.Collections.Generic.List
而且我也惊讶地发现它编译得很好:
IEnumerable<ICollection<int>> anotherlistofLists = new List<List<int>>(); //Works fine (?)
我知道一个简单的 List<List<int>> listofListsWithoutpolymorphism = new List<List<int>>();
会起作用,但我的问题是:
- 第三个和第四个例子有什么区别?
- 如何使用多态实现我需要的东西(比如
ICollecion<IEnumerable<int>>
)?
解决方法
这与实际接口的variance有关,而不是variance >接口实现。
让我们刷新一下:
-
协方差允许方法具有比接口的泛型类型参数定义的返回类型更派生的返回类型
-
相反,不变的接口不允许更多派生的类型
示例中的接口签名:
public interface IEnumerable<out T> : IEnumerable {}
public interface ICollection<T> : IEnumerable<T> {}
让我们用一个人为的例子更容易理解:
public interface ICovariant<out T> { }
public interface IInvariant<T> : ICovariant<T> { }
public class SomeClass<T> : IInvariant<T> { }
测试
// works because `SomeClass` implements IInvariant,type parameters are the same
IInvariant<int> test1 = new SomeClass<int>();
// works because SomeClass implements IInvariant which implements ICovariant,type parameters are the same
ICovariant<int> test2 = new SomeClass<int>();
// works because SomeClass implements IInvariant,type parameters are the same
IInvariant<ICovariant<int>> test3 = new SomeClass<ICovariant<int>>();
// works because IInvariant implements ICovariant,type parameters are the same
ICovariant<IInvariant<int>> test4 = new SomeClass<IInvariant<int>>();
// works because ICovariant is covariant and SomeClass implements IInvariant
// remembering Covariance permits a more derived type
ICovariant<IInvariant<int>> test6 = new SomeClass<SomeClass<int>>();
// hold up,this does not work
// IInvariant is invariant and the type parameters are different!
// an Invariant interface doesn't allow a more derived type
IInvariant<ICovariant<int>> test5 = new SomeClass<SomeClass<int>>();
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。