2010-08-14 36 views
4

的的ToString考慮以下代碼片段:奇法的行爲 - 一個功能

class Program { 
    static void Main(string[] args) { 
    Console.WriteLine(Test().ToString()); 
    } 

    static IEnumerable<char> Test() { 
    foreach (var ch in "test") 
    yield return ch; 
    } 
    static IEnumerable<char> TestOk() { 
    return "test"; 
    } 
} 

Test().ToString()回報 「ConsoleApplication1.Program + d__0」,而不是預期的 「試驗」。

Test()方法甚至沒有執行 - 只是返回它的名字!第二種方法TestOk()工作得很好。

這是怎麼回事?

+4

你確定你沒有做Test.ToString()而不是Test()。ToString()?這應該打印「IEnumerable」而不是它打印的內容。 – 2010-08-14 14:31:23

+0

@Jouke - 它需要30秒來嘗試並親自體驗 - 輸出完全符合規定。 – Justin 2010-08-14 14:37:43

回答

7

它在由編譯器生成的IEnumerable實現上打印ToString方法 - 迭代器只是語法糖 - 生成一個真正的IEnumerable實現。

+0

好的,但有一種方法可以實際執行此方法並獲得預期的字符串(「測試」)? – ddt 2010-08-14 15:05:34

+2

我不知道爲什麼你認爲這是預期的結果。結果是返回每個字符在「測試」中的枚舉。您可以通過遍歷它並連接字符來構建一個字符串。 – 2010-08-14 15:17:12

+0

好的。 'Test()。ToArray()'做這個工作。 – ddt 2010-08-14 15:20:10

2

Test()方法返回一個IEnumerable(char),在這種情況下,它是一個編譯器生成的對象。它的ToString()方法是一個對象的默認值,並返回類型名稱,也是編譯器生成的。

2

所述屈服迴歸方法區別對待是編譯器 - 如果你檢查編譯的程序集使用反射什麼怎麼回事變得更清晰一點:

private static IEnumerable<char> Test() 
{ 
    return new <Test>d__0(-2); 
} 

Wheras TestOk返回一個字符串,Test而是返回一個類編譯器爲您生成。你所看到的是該類的默認字符串表示。

0

其他的答案已經解釋當前的行爲,但如果你想獲得你預期的行爲則不是使用toString()方法可以將IEnumerable<char>轉換爲數組,並使用String構造函數,一個char[]

Console.WriteLine(new string(Test().ToArray()));