gpt4 book ai didi

c# - 返回 IList>

转载 作者:太空狗 更新时间:2023-10-29 20:59:29 28 4
gpt4 key购买 nike

我有一个构建列表列表的方法。我想让返回类型使用通用 IList<> 接口(interface)来减少与下游具体 List<> 类型的耦合。但是,编译器在类型转换方面遇到了困难。

public IList<IList<T>> Foo<T>()
{
return new List<List<T>>();
}

为什么这行得通却失败了:

public IList<T> Foo<T>()
{
return new List<T>();
}

摆脱这种困惑的最优雅的方法是什么?

最佳答案

只需这样做:

return new List<IList<T>>();

因为 List<T>工具 IList<T> ,您将能够添加任何类型的 IList<T>结果。例如:

Foo<int>().Add(new List<int>());

至于为什么,这是协变/逆变的问题(我总是把两者搞混)。基本上,如果你你返回一个IList<IList<T>> , 那么有人应该能够添加任何类型的 IList<T>结果:

Foo<int>().Add(new []{1}); // arrays implement `IList`

显然,如果您返回了一个 List<List<T>>那么上面的代码行将不起作用:您将尝试添加 T[]收藏List<T> .所以即使 List<T>是一个 IList<T> , 一个 List<List<T>>不是 IList<IList<T>> .

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

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

public interface IEnumerable<out T>

那个“out”告诉编译器这个接口(interface)将只有返回T相关的值的方法。 (如 GetEnumerator ),并且它不会有任何采用与 T 相关的方法作为参数(如 Add )。

关于c# - 返回 IList<IList<T>>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8142389/

28 4 0