首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >返回IList<IList<T>>

返回IList<IList<T>>
EN

Stack Overflow用户
提问于 2011-11-16 04:00:14
回答 2查看 11.1K关注 0票数 11

我有一个构建列表列表的方法。我希望返回类型使用通用的IList<>接口,以减少与下游的具体List<>类型的耦合。然而,编译器在类型转换方面遇到了困难。

代码语言:javascript
复制
public IList<IList<T>> Foo<T>()
    {
        return new List<List<T>>();
    } 

当它工作时,为什么它失败:

代码语言:javascript
复制
public IList<T> Foo<T>()
    {
        return new List<T>();
    } 

摆脱这种混乱的最优雅的方法是什么?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-11-16 04:03:18

只需执行以下操作:

代码语言:javascript
复制
return new List<IList<T>>();

因为List<T>实现了IList<T>,所以您可以向结果中添加任何类型的IList<T>。例如:

代码语言:javascript
复制
Foo<int>().Add(new List<int>());

至于原因,这是一个协方差/逆方差的问题(我总是把两者弄混了)。基本上,如果你说你要返回一个IList<IList<T>>,那么某人应该能够在结果中添加任何类型的IList<T>

代码语言:javascript
复制
Foo<int>().Add(new []{1}); // arrays implement `IList`

显然,如果您返回了一个List<List<T>>,那么上面这行代码将无法工作:您将尝试向List<T>的集合中添加一个T[]。因此,即使List<T>IList<T>List<List<T>>也不是IList<IList<T>>

注意:下一部分仅适用于.NET 4和更高版本,因为这是第一个支持接口中的协变和逆变的版本。

另一方面,如果您知道使用您的结果的人并不打算向列表中添加任何内容,而只是试图遍历它,那么您可以将返回类型更改为IEnumerable<IList<T>>,然后完全可以返回一个List<List<T>>。为什么?因为IEnumerable<T>接口是协变的

代码语言:javascript
复制
public interface IEnumerable<out T>

这个"out“告诉编译器,这个接口将只有返回与T相关的值的方法(如GetEnumerator),而不会有任何将与T相关的内容作为参数的方法(如Add)。

票数 18
EN

Stack Overflow用户

发布于 2011-11-16 04:04:26

这与C#协方差和逆方差有关。你可以阅读更多的here

要执行T接口的接口,您的接口必须同时标记为out T或in T。IEnumerable标记为out T。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8142389

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档