为什么 Enumerable.ToLookup<>() 返回 ILookup<,>而不是查找<,>?
Lookup<,>
中有一个方法,而 ILookup<,>
中没有:
public IEnumerable<TResult> ApplyResultSelector<TResult>(
Func<TKey, IEnumerable<TElement>, TResult> resultSelector);
为什么 的返回类型是Enumerable.ToLookup<>()
声明为 ILookup<,>
,尽管事实上它似乎总是返回 Lookup<,>
的实例>?如果返回类型被声明为 Lookup<,>
,则可以在不进行强制转换的情况下使用上述方法。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
设计公共 API 的最佳实践表明,返回接口比返回具体类更好,因为如果需要,您可以返回不同的具体类。 API 的使用者不应依赖于返回的特定类型实例。
正如您所指出的,
ToList
和ToDictionary
返回具体类型而不是接口。也许原因是ToList
和ToDictionary
旨在返回您可以修改的副本(如果您愿意)。由于IList
和IDictionary
接口不能保证它们是可编辑的(这可能是一个坏主意),因此设计者决定返回具体类型。想象一个假设的
ToIList()
方法。如果在数组上调用,则可以实现它以返回数组的副本,因为数组实现了IList
。然后您可能会惊讶地发现调用Add()
会抛出异常。另一方面,
ILookup
是一个只读接口,因此上述内容不适用。因此,没有理由不遵循最佳实践,就像ToList
一样。The best practices for designing public APIs dictate that returning an interface is a better idea than returning a concrete class, because you can then return a different concrete class if you need to. The consumer of the API is not supposed to rely on the returned instance being of a specific type.
As you point out,
ToList
andToDictionary
return concrete types rather than interfaces. Perhaps the reason for this is thatToList
andToDictionary
were meant to return you a copy that you can modify should you want to. Since theIList
andIDictionary
interfaces do not guarantee you that they are editable (which was possibly a bad idea), the designers decided to return the concrete type.Imagine a hypothetical
ToIList()
method. If called on an array, it could be implemented to return you a copy of the array, because arrays implementIList<T>
. You might then be surprised to find out that callingAdd()
throws.On the other hand,
ILookup
is a read-only interface, so the above doesn't apply. Hence there is no reason not to follow the best practice, like there is withToList
.