IEnumerable <t>是接口还是集合?

时间:2018-11-26 15:22:06

标签: c#

据我了解,接口是实施者必须遵循的契约。但在这种情况下:

MessagingException

IEnumerable用作集合类型,不是吗?为什么不做这样的事情?

IEnumerable<int> numQuery = numbers.Where(num => num % 2 == 0).OrderBy(n => n);

我想我错过了一些东西...

3 个答案:

答案 0 :(得分:16)

IEnumerable<T>是表示序列的接口。现在;通常可以将集合用作序列(因此,List<T>实现IEnumerable<T>),但是相反的情况不一定成立。实际上,并不严格要求您甚至可以多次重复序列(IEnumerable<T>)。

许多LINQ操作检查您正在使用的序列是否也是 集合(IList<T>等),以便提供优化的实现({ {1}},而不是通过迭代等进行计数。

.Count等的结果只是:一个序列。它并不会因为您以.Where(...)开头而退回到EnumCollection<T>。对于EnumCollection<T>,数据甚至没有存储在任何地方-它是一个在枚举时应用条件 的过滤器。含义:当您尝试获取下一个项目时,它只是迭代内部序列,丢弃不匹配的项目。在.Where的情况下,它是 缓冲的(根据需要-一般情况下,不进行缓冲就无法排序),但是:这是一个实现细节,通常您不会公开

答案 1 :(得分:5)

IEnumerable绝对是一个界面。

WhereOrderBy是System.Linq提供的针对接口的扩展方法。每个集合类都实现IEnumerable<T>

答案 2 :(得分:1)

接口背后的想法是,您希望使用集合的类仅依赖于它真正需要的特定方法。

您不希望他们访问完整类上的其他方法的原因是,您可能想更改正在使用的基础实现,而无需更改使用它的类

例如,如果您想在其他类中使用EnumCollection,那么您将被明确绑定到该实现。而如果您在using类中使用了该接口,则可以将EnumCollection的实现换成StringCollection,并且您的类仍然可以工作,因为它们只需要IEnumerable接口。

这源于SOLID中的I。 https://en.wikipedia.org/wiki/SOLIDhttps://en.wikipedia.org/wiki/Interface_segregation_principle

请注意List类如何具有许多MANY接口;

/// ('a -> Envelope<'a>) -> Envelope<'a> -> Envelope<'a>
let mapIfErrors f e =
    match e.Errors with
    | [] ->   e
    | _  -> f e.Content 

/// ('a -> string list -> Envelope<'a>) -> Envelope<'a> -> Envelope<'a>
let mapIfErrors2 f e =
    match e.Errors with
    | [] ->   e
    | _  -> f e.Content e.Errors

...并且HashSet类共享其中的一些...

key

来自https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.list-1?view=netframework-4.7.2