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

  • 本文关键字:集合 接口 IEnumerable c#
  • 更新时间 :
  • 英文 :


据我所知,接口是实现者必须遵守的契约。但在这种情况下:

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绝对是一个接口。

CCD_ 13和CCD_ 14是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

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

最新更新