tags:

views:

255

answers:

7

I was checking some of the code that make up LINQ extensions in Reflector, and this is the kind of code I come across:

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;
}

Was there a reason for Microsoft to write it this way?

Also what does the <> syntax mean, in lines like:

switch (this.<>1__state)

I have never seen it written before a variable, only after.

+2  A: 

Identifiers starting with <> aren't valid C# identifiers, so I suspect they use them to mangle the names without fear of conflict, as no identifier in the C# code could be the same.

As to why it's hard to read, I suspect that it's more down to the fact it's easy to generate.

ICR
Thanks but I don't understand how other code would conflict with this?
Joan Venge
Joan, other code WON'T conflict with this. That's the point. The compiler chooses intentionally illegal identifier names for its generated code so it can't possibly interfere with the user-written code it's compiling.
Rob Kennedy
Not code, variable names.You cannot have a variable name that contains <>, so nothing can conflict with it
SLaks
+2  A: 

This is code that is automatically generated when you use iterators. The <> is used to ensure there are no collisions, and also to prevent you from accessing the compiler-generator classes directly in your code.

See the following for more information:

Talljoe
I didn't know <> characters were valid for variables.
Joan Venge
They're not valid in C# but they are in IL. This means that the compiled code is perfectly legal, but you can't access the auto-generated types in your own code. It also means that the compiler can guarantee that the (illegal in C#) names of auto-generated types won't clash with the (legal in C#) names of any other types.
LukeH
+8  A: 

The MSIL is still valid 2.x code and the <> names you're seeing are auto generated by the C# 3.x compilers.

For example:

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

Translates to something like:

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

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

I should also note that the reason you're seeing it like that in Reflector is that you don't have .NET 3.5 optimization turned on. Go to View | Options and change Optimization to .NET 3.5 and it will do a better job of translating the generated identifiers back to their lamda expressions.

Paul Alexander
I thought that those types of names were chosen to make sure that the names chosen do not conflict with anything you choose.
RCIX
+2  A: 

These are types that have been auto-generated by the compiler from iterator methods.

The compiler will do exactly the same sort of thing to your own iterators. For example, write something like this and then take a look at the actual generated code in Reflector:

public IEnumerable<int> GetRandom()
{
    Random rng = new Random();

    while (true)
    {
        yield return rng.Next();
    }
}
LukeH
+2  A: 

This is state machine that is automatically generated from an iterator, such as the following:

static IEnumerable<Func<KeyValuePair<int, int>>> FunnyMethod() {
    for (var i = 0; i < 10; i++) {
        var localVar = i;
        yield return () => new KeyValuePair(localVar, i);
    }
}

This method will return 10 for all of the values.

The compiler transforms these methods into state machines that store their state in the <>1__state field and call each part of the iterator for a different value of the field.

The <> part is part of the generated field name, and is chosen so as not to conflict with anything.

SLaks
A: 

You must understand what Reflector does. It is not getting the source code back. That's not what a developer at MS wrote. :) It takes Intermediate Language (IL) and systematically converts it back to C# (or VB.NET). In doing so, it must come up with an approach. As you know there are many ways to skin a cat in code that will eventually lead to the same IL. Reflector has to pick a way to move back wards from IL to a higher level language and use that way every time.

(Fixed per comment, thank you.)

JP Alioto
These are not names picked by reflector. These are names generated by the compiler and used in the IL, as others have mentioned.
configurator
+7  A: 

You're seeing the internal guts of the finite state machines that the C# compiler emits on your behalf when it handles iterators.

Jon Skeet has some great articles (Iterator block implementation details and Iterators, iterator blocks and data pipelines) on this subject. See also Chapter 6 of his book.

There was previously an SO post on this subject.

And, finally, Microsoft Research has a nice paper on the subject.

Read until your heart is content.

Jason