[英]Is IEnumerable<T> an Interface or a Collection?
据我了解,接口是实施者必须遵循的契约。 但是在这种情况下:
IEnumerable<int> numQuery = numbers.Where(num => num % 2 == 0).OrderBy(n => n);
IEnumerable用作集合类型不是吗? 为什么不做这样的事情?
public class EnumCollection<T> : IEnumerable<T>
{
}
EnumCollection<T> numQuery = numbers.Where(num => num % 2 == 0).OrderBy(n => n);
我想我错过了什么...
IEnumerable<T>
是表示序列的接口。 现在; 集合通常可以用作序列(因此... List<T>
实现IEnumerable<T>
),但是反之并不一定成立。 实际上,并不严格要求您甚至可以多次重复序列( IEnumerable<T>
)。
许多LINQ操作会检查您正在使用的序列是否也是一个集合( IList<T>
等),以便提供优化的实现( .Count
而不是通过迭代进行计数等)。
.Where(...)
等的结果只是:一个序列。 它不转换回一个EnumCollection<T>
仅仅因为你开始与EnumCollection<T>
在.Where
的情况下,数据甚至没有存储在任何地方-它是一个在枚举时应用条件的过滤器。 含义:当您尝试获取下一个项目时,它只是迭代内部序列,丢弃不匹配的项目。 在OrderBy
的情况下,它是被缓冲的(根据需要-通常情况下,如果不进行缓冲就无法排序),但是:这是您通常不了解的实现细节。
IEnumerable
绝对是一个接口。
Where
和OrderBy
是System.Linq提供的扩展方法 ,它们对接口起作用。 每个集合类都实现IEnumerable<T>
接口背后的想法是,您希望使用集合的类仅依赖于它真正需要的特定方法。
您不希望他们访问完整类上的其他方法的原因是,您可能希望更改正在使用的基础实现, 而不更改使用它的类 。
例如,如果您想在其他类中使用EnumCollection,那么您将被明确绑定到该实现。 而如果您在using类中使用了该接口,则可以将EnumCollection的实现换成StringCollection,并且您的类仍然可以工作,因为它们只需要IEnumerable接口。
这源于SOLID中的I。 https://en.wikipedia.org/wiki/SOLID和https://en.wikipedia.org/wiki/Interface_segregation_principle
注意List类有许多MANY接口。
[Serializable]
public class List<T> : System.Collections.Generic.ICollection<T>, System.Collections.Generic.IEnumerable<T>, System.Collections.Generic.IList<T>, System.Collections.Generic.IReadOnlyCollection<T>, System.Collections.Generic.IReadOnlyList<T>, System.Collections.IList
...并且HashSet类共享其中的一些...
[Serializable]
public class HashSet<T> : System.Collections.Generic.ICollection<T>, System.Collections.Generic.IEnumerable<T>, System.Collections.Generic.IReadOnlyCollection<T>, System.Collections.Generic.ISet<T>, System.Runtime.Serialization.IDeserializationCallback, System.Runtime.Serialization.ISerializable
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.