我正在查看Entity Framework 4的一些代码示例,并且作者创建了一个返回ICollection <Person>的方法。我知道ICollection是一个接口。我知道Person是集合中的对象的类型。我知道我找回了一批人。返回类型ICollection <Person>是什么意思?
这个问题。为什么选择ICollection?为什么不列出<>?为什么这样使用接口?我使用接口作为类的“蓝图”,指定了所需的成员,但我并不真正了解这里的用法。
我正在查看Entity Framework 4的一些代码示例,并且作者创建了一个返回ICollection <Person>的方法。我知道ICollection是一个接口。我知道Person是集合中的对象的类型。我知道我找回了一批人。返回类型ICollection <Person>是什么意思?
这个问题。为什么选择ICollection?为什么不列出<>?为什么这样使用接口?我使用接口作为类的“蓝图”,指定了所需的成员,但我并不真正了解这里的用法。
在公共API中返回接口而不是具体类通常更好。
这允许稍后更改实施。例如,它现在可能正在返回List<T>
。然而,稍后,可以进行优化以返回不同类型的集合,其可以具有更好的存储效率,允许流式传输或其他优点之一。只要该类仍然实现ICollection<T>
,该实现可以自由切换而不会导致API发生突变。
GoF Design Patterns这本书的重点之一是编程到一个接口,而不是一个实现。其原因是它提供的自由。通过返回一个接口而不是一个特定的类型,可以在不影响调用代码的情况下更容易地改变实现。
除非您的用户需要您的API,否则您的API应尽可能少地暴露实现细节,在这种情况下,使用List<Person>
是实现细节。例如,如果您或您的用户知道他们想要按索引访问结果集,那么最好返回IList<Person>
而不是ICollection<Person>
,但如果您不确定用户场景,则应尽可能公开最基本的抽象(即在这种情况下可能IEnumerable<Person>
就足够了)。请记住,如果最近您决定使用更多的派生返回类型,它不会破坏任何现有的客户端,但是您不能使用更多的基于类型的返回类型,而不会破坏其中的某些返回类型。
正如IEnumerable和其他这样的接口遍布.net。 – Mark 2010-09-10 17:23:18
一个很好的例子是在使用'yield return'时返回IEnumerable:http://msdn.microsoft.com/en-us/library/9k7k7cf0.aspx。使用这种组合,您不必在返回之前填充整个列表。如果用户只对部分列表感兴趣,则只有他们阅读的部分将被填充。这也可以简化生成列表的代码,因为您不必创建临时列表来返回结果。 –
2010-09-10 17:24:54
是 - IEnumerable比ICollection 更灵活,但ICollection 反过来比IList 更灵活。您返回的界面越简单,以后用于更改实施的选项越多...... –
2010-09-10 17:35:28