为什么C#编译器使用foreach语句分别处理字符串类

时间:2011-07-04 14:23:59

标签: c# foreach

我清楚地理解在处理foreach语句时使用C#编译器的"Pattern-based" approach

从C#语言规范(第8.8.4节)可以看出,首先C#编译器尝试查找GetEnumerator方法,然后才尝试查找IEnumerable<T>IEnumerable接口

但我不清楚,为什么C#编译器会单独处理string(因为String类包含一个返回CharEnumerator的方法GetEnumerator,它也实现了{{1} }和IEnumerable<char> interfces):

IEnumerable

转换为

string s = "1234";
foreach(char c in s)
  Console.WriteLine(c);

但我在语言规范中找不到关于string s = "1234"; for(int i = 0; i < s.Length; i++) Console.WriteLine(s[i]); 类的任何例外。有人可以就这个解决方案提供一些见解吗?

我尝试使用C#4编译器。以下是上一个代码段的IL代码:

String

1 个答案:

答案 0 :(得分:21)

好抓。我知道编译器对数组执行了类似的优化,但我不知道它也是为字符串执行此操作。

我能得到的最好的是来自language specification的召唤,只要它产生相同的行为,就会使编译器有权偏离'canon':

  

8.8.4 foreach声明

     

[...]表格的foreach声明   foreach (V v in x) 嵌入式声明   然后扩展到:

{
    E e = ((C)(x)).GetEnumerator();
    try {
        V v;
        while (e.MoveNext()) {
            v = (V)(T)e.Current;
            embedded-statement
        }
    }
    finally {
        … // Dispose e
    }
}
  

[...] 允许实施   实施一个给定的foreach声明   不同的,例如为了表现   原因,只要是行为   与上述扩展一致。