我一直被告知对接口编程更好,所以我的方法参数设置为IList<T>
而不是List<T>
..
但这意味着我必须投射到List<T>
只是为了使用某些方法,例如我想到的是Find
。
这是为什么?我应该继续针对接口进行编程,还是继续进行转换或还原?
我有点困惑,为什么Find
(例如)在IList<T>
继承的List<T>
上不可用。
答案 0 :(得分:11)
我个人会使用IList<T>
而不是List<T>
,但是然后使用LINQ(Select
,Where
等)而不是特定于列表的方法。
转换为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,有额外的方法。