2010-08-11 81 views
9

这个IEnumerable<string>的具体类型是什么?什么具体类型'收益回报'回报?

private IEnumerable<string> GetIEnumerable() 
{ 
    yield return "a"; 
    yield return "a"; 
    yield return "a"; 
} 
+1

这是语法糖。引擎盖下正在发生很多事情。更快的方式看到它是使用反射器。它基本上创建了一个保持状态的类,并在调用GetNext()或类似的东西时返回“a”。 – 2010-08-11 00:08:45

+0

@Timwi感谢编辑:) – stacker 2010-08-11 00:23:23

回答

7

这是一个编译器生成的类型。编译器生成一个IEnumerator<string>实现,该实现返回三个“a”值和一个IEnumerable<string>骨架类,该类在其GetEnumerator方法中提供了其中的一个。

生成的代码看起来东西这样*:

// No idea what the naming convention for the generated class is -- 
// this is really just a shot in the dark. 
class GetIEnumerable_Enumerator : IEnumerator<string> 
{ 
    int _state; 
    string _current; 

    public bool MoveNext() 
    { 
     switch (_state++) 
     { 
      case 0: 
       _current = "a"; 
       break; 
      case 1: 
       _current = "a"; 
       break; 
      case 2: 
       _current = "a"; 
       break; 
      default: 
       return false; 
     } 

     return true; 
    } 

    public string Current 
    { 
     get { return _current; } 
    } 

    object IEnumerator.Current 
    { 
     get { return Current; } 
    } 

    void IEnumerator.Reset() 
    { 
     // not sure about this one -- never really tried it... 
     // I'll just guess 
     _state = 0; 
     _current = null; 
    } 
} 

class GetIEnumerable_Enumerable : IEnumerable<string> 
{ 
    public IEnumerator<string> GetEnumerator() 
    { 
     return new GetIEnumerable_Enumerator(); 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return GetEnumerator(); 
    } 
} 

或者,也许,作为SLaks说,在他的回答中,两种实现在同一个类中结束。我基于我以前看过的生成代码的不稳定内存来编写它。实际上,一个类就足够了,因为没有理由上述功能需要两个。

其实,细想起来,这两种实现真正应该秋天一个类中,我只记得使用yield语句的功能必须有要么IEnumerable<T>IEnumerator<T>返回类型。

无论如何,我会让你执行我精神上发布的代码更正。

*这纯粹是为了说明的目的;我没有声称它的真实准确性。根据我在我自己的调查中看到的证据,它只是以一般的方式展示编译器如何执行它的功能。

+2

此外,编译器生成的类型将在您的示例中具有名称' d__0'。 (是的,'<' and '>'是*类型名称*的一部分,您不能在C#中编写这样的类型名称,但它在CLR中是有效的。)类型嵌套在声明'GetIEnumerable() '方法。 – Timwi 2010-08-11 00:12:46

7

编译器会自动生成一个实现IEnumerable<T>IEnumerator<T>(在同一个类中)的类。

Jon Skeet has a detailed explanation

+0

+1。 – stacker 2010-08-11 00:47:19

+1

请将链接的相关部分添加到您的答案中 – 2016-06-19 01:09:06

2

具体实现的IEnumerable<string>该方法返回是由编译器

Console.WriteLine(GetIEnumerable().GetType()); 

打印产生一个匿名类型:

YourClass+<GetIEnumerable>d__0