2010-08-11 99 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