IEnumerable <T>如何在后台运行

Igo*_*evo 2 c# linq oop ienumerable interface

我正在徘徊于IEnumerable<T>界面的更深入的功能.

基本上,它作为执行中的中间步骤.例如,如果你写:

IEnumerable<int> temp = new int[]{1,2,3}.Select(x => 2*x);
Run Code Online (Sandbox Code Playgroud)

Select函数的结果将不会被计算(枚举),直到用temp来完成某些事情(例如List<int> list = temp.ToList()).

但是,让我感到困惑的是,因为它IEnumerable<T>是一个接口,所以根据定义它不能被实例化.那么,实际项目(在示例2*x项目中)所包含的集合是什么?

而且,如果我们要编写IEnumerable<int> temp = Enumerable.Repeat(1, 10);,那么存储1的底层集合是什么(数组,列表,其他东西)?

我似乎无法找到关于此接口及其功能的实际实现的详尽(更深入)解释(例如,如果存在底层集合,yield关键字如何工作).

基本上,我要求的是对功能的更详细的解释IEnumerable<T>.

Mar*_*zek 5

实施无关紧要.所有这些(LINQ)方法都返回IEnumerable<T>,接口成员是您可以访问的唯一成员,这应该足以使用它们.

但是,如果您真的必须知道,可以在http://sourceof.net上找到实际的实现.

但是,对于某些方法,您将无法找到显式类声明,因为它们中的一些使用yield return,这意味着编译期间编译器会生成正确的类(带状态机).例如Enumerable.Repeat以这种方式实现:

public static IEnumerable<int> Range(int start, int count) {
    long max = ((long)start) + count - 1;
    if (count < 0 || max > Int32.MaxValue)
        throw Error.ArgumentOutOfRange("count");
    return RangeIterator(start, count); 
}

static IEnumerable<int> RangeIterator(int start, int count) {
    for (int i = 0; i < count; i++)
        yield return start + i;
}
Run Code Online (Sandbox Code Playgroud)

您可以在MSDN上阅读更多相关信息:迭代器(C#和Visual Basic)

  • 为什么投票失败?这是这个问题的一个真正有效的答案.它是一个接口,框架隐藏了实现,那么呢?应该给出+2只是为了链接实现的源代码. (2认同)