为什么LINQ扩展以非常难以阅读的方式编写?

Joa*_*nge 2 .net c# linq

我正在检查构成Reflector中LINQ扩展的一些代码,这是我遇到的那种代码:

private bool MoveNext()
{
    bool flag;
    try
    {
        switch (this.<>1__state)
        {
            case 0:
                this.<>1__state = -1;
                this.<set>5__7b = new Set<TSource>(this.comparer);
                this.<>7__wrap7d = this.source.GetEnumerator();
                this.<>1__state = 1;
                goto Label_0092;

            case 2:
                this.<>1__state = 1;
                goto Label_0092;

            default:
                goto Label_00A5;
        }
    Label_0050:
        this.<element>5__7c = this.<>7__wrap7d.Current;
        if (this.<set>5__7b.Add(this.<element>5__7c))
        {
            this.<>2__current = this.<element>5__7c;
            this.<>1__state = 2;
            return true;
        }
    Label_0092:
        if (this.<>7__wrap7d.MoveNext())
        {
            goto Label_0050;
        }
        this.<>m__Finally7e();
    Label_00A5:
        flag = false;
    }
    fault
    {
        this.System.IDisposable.Dispose();
    }
    return flag;
}
Run Code Online (Sandbox Code Playgroud)

微软是否有理由以这种方式编写它?

另外,<>语法的含义如下:

switch (this.<>1__state)
Run Code Online (Sandbox Code Playgroud)

我之前从未见过它在变量之前写过.

Pau*_*der 8

MSIL仍然是有效的2.x代码,您看到的<>名称是由C#3.x编译器自动生成的.

例如:

public void AttachEvents()
{
    _ctl.Click += (sender,e) => MessageBox.Show( "Hello!" );
}
Run Code Online (Sandbox Code Playgroud)

转换为:

public void AttachEvents()
{
    _ctl.Click += new EventHandler( <>b_1 );
}

private void <>b_1( object sender, EventArgs e )
{
    MessageBox.Show( "Hello!" );
}
Run Code Online (Sandbox Code Playgroud)

我还应该注意,你在Reflector中看到它的原因是你没有打开.NET 3.5优化.转到视图| 选项和更改优化到.NET 3.5,它可以更好地将生成的标识符转换回其lamda表达式.


jas*_*son 7

您正在看到C#编译器在处理迭代器时代表您发出的有限状态机的内部内容.

Jon Skeet 在这个主题上有一些很棒的文章(迭代器块实现细节迭代器,迭代器块和数据管道).另见他的书的第6章.

以前的SO后在这个问题上.

最后,微软研究院有一篇关于这个主题的好文章.

阅读,直到你的心满意为止.