Iterators OR Excuse me waiter theres a goto in my C sharp

At Codestock '09, I gave my LINQ Internals talk and had a number of people express shock when I showed the underlying implementation of their beloved iterators when looking at the code through Reflector. Let's look first at the C# that we wrote. This is similar to the implementation of LINQ to Object's Where method as shown in the sequence.cs file that's part of the C# Samples.


public static IEnumerable Where(this QueryableString source, Func predicate)
{
   foreach (char curChar in source)
        if (predicate(curChar))
            yield return curChar;
}

C# Iterators aren't really first class citizens, but syntactic sugar around the actual implementation. The meat of the implementation occurs in a generated class that implements the actual MoveNext method as we foreach over the results. The results are much less pretty:


private bool MoveNext()
{
    bool CS$1$0000;
    try
    {
        switch (this.1__state)
        {
            case 0:
                break;

            case 2:
                goto Label_0087;

            default:
                goto Label_00A5;
        }
        this.1__state = -1;
        this.7__wrap2 = this.4__this.GetEnumerator();
        this.1__state = 1;
        while (this.7__wrap2.MoveNext())
        {
            this.<curString>5__1 = this.7__wrap2.Current;
            if (!this.predicate(this.<curString>5__1))
            {
                continue;
            }
            this.2__current = this.<curString>5__1;
            this.1__state = 2;
            return true;
        Label_0087:
            this.1__state = 1;
        }
        this.m__Finally4();
    Label_00A5:
        CS$1$0000 = false;
    }
    fault
    {
        this.System.IDisposable.Dispose();
    }
    return CS$1$0000;
}

As you can see, the iterator sets up a switch (Select Case) statement that checks to see where we are in the loop (using a state variable). Essentially this is a state machine. The first time through we set up the environment. As we iterate over the results, we call the predicate that was passed in. If the predicate evaluates as true, we exit out of the method returning true.

The next time we return to the MoveNext, we use goto Label_0087 to re-enter the loop and continue the iteration. It's at this point that the jaws dropped in my presentation. Yes, Virginia, there are "Goto's" in C#. Spaghetti code isn't limited to VB. It's this point in my presentation where I quipped that the reason why iterators aren't in VB yet is because we want to do them "Right". While this is partly a joke, there is a level of seriousness in the comment. If you want to dig deeper on iterators, I recommend the following for your reading pleasure (note, these are NOT for the faint of heart):

After reading these, I'm sure you will have a better understanding of why it is taking so long to get iterators in VB. In the mean time, you might also find Bill McCarthy's recent article on using Iterators in VB Now to be interesting.

Posted on 6/29/2009 4:30:00 PM - Comments (1)
Categories: VB , C# , LINQ

LINQ Tools coming to Russ Tool Shed

Russ Fustino and Stan Schultes have recently started bringing their popular Russ' Tool Shed show to the internet. If you want to check out the show, head on over to http://channel9.msdn.com/shows/toolshed. They also have all of the resources, including source code, slides, and demo scripts available at http://channel9.msdn.com/toolshed. I was there when they recorded the first episode at the South Florida code camp as an attendee.

We're hoping to do a recording at one of the upcoming Florida Code Camps to look at LINQ related tools. I'm planning on covering the following tools.

All of these tools are free (a requirement of the Code Camp manifesto). I may add a couple tools, but only have 10 minutes to cover everything. Let me know if you have a favorite tool that's not on this list.

Posted on 6/29/2009 9:07:00 AM - Comments (0)
Categories: LINQ , Code Camp

LINQ in Action XML samples added to LINQPad

The beginning of this month, we released the samples from "LINQ in Action" for chapters 1-8 which covers LINQ to Objects, LINQ to SQL, and the new Language features. We're happy to announce that the next three chapters covering LINQ to XML are now available. That's over 70 new samples in VB and C# each. Follow the directions on the original announcement to download and use these samples.

Posted on 6/28/2009 2:03:00 PM - Comments (2)
Categories: Linq to XML , LinqPad

Upcoming Speaking engagements

The speaking scene in the South East has been quiet for a bit but is starting to pick up. Here's a quick list of my upcoming speaking engagements starting this weekend. If you're near one of these, stop by and say hi.

If you attended any of these talks and didn't fill out an evaluation from the conference organizers, I would appreciate it if you let me know what you thought about the talk at http://www.speakerrate.com/jwooley. Make sure to include comments so that I can make future talks better.

Posted on 6/25/2009 4:22:00 PM - Comments (0)
Categories: Code Camp

More Ways to create an XML file

Edward Tanguay just posted three comparative examples of creating XML files via String Concatenation, XmlWriter, and LINQ to XML. I would typically respond to a blog post through that site's comments, but public comments are blocked at this point. While his post is a good start and shows pretty easily the simplicity that using LINQ to XML gives over the other options, he does fail to address a couple other options:

  • XmlDocument
  • Serialized objects, and of course
  • XML Literals with VB.

Before discussing each of these options, I want to take a minute to address the real issues with the string concatenation sample. While it is relatively easy to use string concatenation to build up the XML, it can be quite dangerous. The main issue is the ease at which you can add invalid characters into the XML elements. In particular, if your variable has one of the characters that need to be escaped (like & or <), using the sample code will cause invalid XML to be generated. You have to properly escape all of the variables which can quickly make the code much more complex. Luckily each of the other XML options handle escaping these values correctly for you automatically.

On to the other options. While you could use the XmlDocument rather than XmlWriter, coding it is much more complex. Also, it doesn't allow for streaming the results out which causes a higher memory footprint as the entire document will be in memory.

Serialized objects give a nice type-safe option, but they do require you to code the object structures before you can consume them. Using tools like XSD.exe or LINQ to XSD helps reduce this overhead, but it is something to be aware of.

I would be remiss if I didn't offer a XML Literal option, so here you go. Here's Edward's C# Sample for reference purposes:

 
XDocument doc = new XDocument(
                new XDeclaration("1.0", null, null),
                new XElement(_pluralCamelNotation,
                    Enumerable.Range(1, 3).Select(
                        i => new XElement(_singularCamelNotation,
                            _allDataTypes.Select(
                                dataType => new XElement(
                                    dataType.CamelCaseNotation,
                                    dataType.GetDummyData())
                            )
                    ))));
            return doc.ToString();

And here's the VB equivalent using XML Literals:


Dim doc = <?xml version="1.0"?>
          <<%= _pluralCamelNotation %>>
              <%= From i In Enumerable.Range(1, 3) _
                  Select <<%= _singluarNotation %>>
                           <%= From t In _allDataTypes _
                               Select <<%= t.CamelCaseNotation %>>
                                           <%= t.GetDummyData %></> %>
                           </> %>
               </>
As it is, we are able to drop a couple lines from the C# code. However, this example is a bit less consise as some XML Literal examples because we are not only inserting the element's values, but the names of the elements themselves dynamically through the literal. As a result there are a number of cases where we have double opening XML tags (<<) which detracts from the readability somewhat. Choosing to use LINQ expressions over Lambda's is purely a matter of style and preference.

Posted on 6/24/2009 9:04:00 PM - Comments (0)
Categories: Linq to XML

    Next