微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在 C# 中对列表列表使用多态性

如何解决如何在 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' 到 'System.Collections.Generic.ICollection'。 存在显式转换(您是否缺少强制转换?)

而且我也惊讶地发现它编译得很好:

IEnumerable<ICollection<int>> anotherlistofLists = new List<List<int>>(); //Works fine (?)

我知道一个简单的 List<List<int>> listofListsWithoutpolymorphism = new List<List<int>>(); 会起作用,但我的问题是:

  1. 第三个和第四个例子有什么区别?
  2. 如何使用多态实现我需要的东西(比如 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 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?