为什么IList <t>没有提供List <t>的所有方法?我该使用哪种?</t> </t>

时间:2011-03-04 13:25:48

标签: c# .net generics interface

我一直被告知对接口编程更好,所以我的方法参数设置为IList<T>而不是List<T> ..

但这意味着我必须投射List<T>只是为了使用某些方法,例如我想到的是Find

这是为什么?我应该继续针对接口进行编程,还是继续进行转换或还原?

我有点困惑,为什么Find(例如)在IList<T>继承的List<T>上不可用。

8 个答案:

答案 0 :(得分:11)

我个人会使用IList<T>而不是List<T>,但是然后使用LINQ(SelectWhere等)而不是特定于列表的方法。

转换为List<T>首先消除了使用IList<T>的大部分要点 - 并且实际上使其更加危险,因为实现可能是其他而不是{ {1}}在执行时。

答案 1 :(得分:6)

对于列表,您可以继续对接口进行编程,并使用LINQ过滤对象。您甚至可以使用对象层次结构中更高的IEnumerable<T>

但更一般地说,如果你的API的消费者需要调用特定的方法,你可能没有选择适当的接口来公开。

答案 2 :(得分:2)

  

我有点困惑为什么查找   (例如)不可用   列表继承自的IList。

虽然我不了解设计师的决策过程,但他们可能会想到一些事情。

1)不将这些方法放在IList上可以使合同的意图更加清晰。根据MSDN,IList“表示可以通过索引单独访问的对象集合”。添加查找会将合同更改为可搜索,可索引的集合。

2)您在界面上放置的每个方法都会使实现界面变得更加困难。如果所有这些方法都在IList上,那么实现IList会更加繁琐。特别是因为:

3)这些方法的大多数实现都是相同的。查找和列表中的其他几个实际上会更好地放在辅助类上。例如,ReadOnlyCollection,Collection,ObservableCollection和ReadOnlyObservableCollection。如果我必须在所有这些(LINQ之前)上实现Find,我会创建一个辅助类,它接受IEnumerable和谓词,只是循环遍历集合并让实现调用辅助方法。

4) LINQ (不是为什么它没有发生的原因,更多的是为什么将来不需要它。)使用LINQ和扩展方法,所有IEnumerable现在都“有” “查找作为扩展方法(只有他们称之为”)。

答案 3 :(得分:1)

我认为这是因为IList可以是不同的集合类型(即某种类型的IEnumerable,一个数组左右)。

您可以使用System.Linq中的Where扩展方法。避免从IList转回List。

答案 4 :(得分:1)

如果您发现在各个类之间传递的IList<T>参数始终重新转换为List<T>,则表明您的设计存在根本问题。

从您所描述的内容来看,很明显您想要使用多态,但是在List<T>的基础上重新进行重构将意味着IList<T>没有您需要的多态性级别。< / p>

在硬币的另一面,你可能只是针对错误的多态方法(例如,Find而不是FirstOrDefault)。

在任何一种情况下,您都应该检查您的设计,看看您想要完成什么,并根据实际要求选择List<T>IList<T>,而不是符合风格

答案 5 :(得分:1)

如果您使用IList&lt;&gt;公开您的方法参数,例如,某人可以传递ReadOnlyCollection&lt;&gt;,女巫 IList&lt;&gt;但不是列表&lt;&gt;。所以你的API会在运行时崩溃。 如果您使用IList&lt;&gt;公开公共方法参数,您不能假设它是IList&lt;&gt;的特定实现。您必须将其用作IList&lt;&gt;没有更多。

答案 6 :(得分:0)

如果列表是暴露的Api或服务的某些部分,那么作为IList允许在内部更改实现可能更好。

此主题已有much discussion

答案 7 :(得分:0)

不,在这种情况下,编程接口是没有意义的,因为你的List不是IList,有额外的方法。