<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-US"><title type="html">Cyrus&amp;#39; Blather</title><subtitle type="html" /><id>http://blogs.msdn.com/b/cyrusn/atom.aspx</id><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/cyrusn/" /><link rel="self" type="application/atom+xml" href="http://blogs.msdn.com/b/cyrusn/atom.aspx" /><generator uri="http://telligent.com" version="5.6.50428.7875">Telligent Evolution Platform Developer Build (Build: 5.6.50428.7875)</generator><updated>2005-09-13T04:40:00Z</updated><entry><title>C# Express is Alive.  IT'S ALIVE!!!</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/cyrusn/archive/2005/11/07/489909.aspx" /><id>http://blogs.msdn.com/b/cyrusn/archive/2005/11/07/489909.aspx</id><published>2005-11-07T21:32:00Z</published><updated>2005-11-07T21:32:00Z</updated><content type="html">I'm proud to tell you all about the availabilty *today* of C# Express
for the insanely high price of $0.&amp;nbsp; That's right.&amp;nbsp; You can
get streamlined and slick version of Visual Studio with complete
support for C# editing, WinForms development and debugging for
FREE!&amp;nbsp; I worked hard on this product (from the feature level all
the way to Sku creation) and i'm incredibly proud of it.&amp;nbsp; Having a
free development platform is something that i've been wanting to
provide ever since i came to the company.&amp;nbsp; You were always able to
develop on windows for free using the SDKs we've provided.&amp;nbsp;
However, there's a vast difference between using notepad and a csc.exe
and having a rich development environment that can make development so
much faster.&lt;br&gt;
&lt;br&gt;
So if you want a great,&amp;nbsp; free IDE head over to the &lt;a href="http://msdn.microsoft.com/vstudio/express/visualcsharp/"&gt;C# Express&lt;/a&gt;
page and go get it.&amp;nbsp; Or, heck, if you want to try out the IDE to
see what it's like before shooting for one of it's more expsensive
simplblings, you now can find out what they're like without needing a
beta.&amp;nbsp; And, i might as well mention it, if you want great, free &lt;a href="http://msdn.microsoft.com/vstudio/express/vb/"&gt;VB&lt;/a&gt;, &lt;a href="http://msdn.microsoft.com/vstudio/express/visualc/"&gt;C++&lt;/a&gt;, &lt;a href="http://msdn.microsoft.com/vstudio/express/vwd/default.aspx"&gt;ASP.Net&lt;/a&gt;, &lt;a href="http://msdn.microsoft.com/vstudio/express/visualj/"&gt;J#&lt;/a&gt; tools or even &lt;a href="http://msdn.microsoft.com/vstudio/express/sql/default.aspx"&gt;SQL Server&lt;/a&gt;, you can get those for free as well!!!&lt;br&gt;
&lt;br&gt;
This is an awesome day for me and i hope it is for you as well!&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=489909" width="1" height="1"&gt;</content><author><name>CyrusN</name><uri>http://blogs.msdn.com/CyrusN/ProfileUrlRedirect.ashx</uri></author></entry><entry><title>OMG.  I can't believe it's over!</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/cyrusn/archive/2005/10/27/486013.aspx" /><id>http://blogs.msdn.com/b/cyrusn/archive/2005/10/27/486013.aspx</id><published>2005-10-28T05:56:00Z</published><updated>2005-10-28T05:56:00Z</updated><content type="html">&lt;P&gt;Well, unless you've been living under a rock, you know that we finally signed off on VS 2005 and that it's available now (or soon) to MSDN subscribers.&amp;nbsp; The "boxed" versions should be coming in just a few weeks, and i can't wait to see what you think about it.&amp;nbsp; I was involved in many parts of the VS2005 release, including:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Working heavily on the C# IDE experience.&amp;nbsp;&amp;nbsp; Primarily IntelliSense, but also in a myriad of other design time components&lt;/LI&gt;
&lt;LI&gt;Working some on the C# compiler.&lt;/LI&gt;
&lt;LI&gt;Working on creating the C# Express SKU.&amp;nbsp; I was heavily involved in piecing things together and helping with componentization so that we could sculpt vs into the lean and mean app that is C# express&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;So this is a huge release for me.&amp;nbsp; I wasn't involved with 2k3 and so i don't really feel strongly about that tool.&amp;nbsp; But with 2k5 you're going to be using my code (potentially for hours upoin hours every day) and that's a huge thing for me.&amp;nbsp; I'm feeling a rush of emotions right now like you wouldn't believe.&amp;nbsp; Tons of excitement, but also a lot of fear.&amp;nbsp; Will you guys like what we've done?&amp;nbsp; Will you *love* it?&amp;nbsp; Will i be the one who introduced a bug that you're going to be cursing out for months?&amp;nbsp; Who knows?!&lt;/P&gt;
&lt;P&gt;Now, with teh release of Whidbey i can start setting my sites on Orcas.&amp;nbsp; As you've probably been able to tell, i've taken on a position of helping to craft what will eventually become the C# 3.0 language.&amp;nbsp; It's my hope that as you all start using 2.0 day in and day out you can then work with us (and us with you) on trying to make 3.0 awesome.&amp;nbsp;&amp;nbsp; Toward that goal i've already tried to be intimitely involved in the prototyping we've been doing.&amp;nbsp; If you're tried out the Beta2 preview then you're using code that i was actively involved with creating.&amp;nbsp; I'd like to talk about that a lot more at some point, but that will have to wait.&amp;nbsp; But for now, i wanted to let you know that we've updated the Linq preview bits to work with the RTM version of VS2005.&amp;nbsp; You can find the download for that on the linq page here: &lt;A href="http://msdn.microsoft.com/netframework/future/linq/"&gt;http://msdn.microsoft.com/netframework/future/linq/&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;I'm going to be very clear here: Do not run these bits on Beta2.&amp;nbsp; And do not run the Beta2 bits on RTM.&amp;nbsp; There were binary breaking changes and things will crash almost immediately :-)&lt;/P&gt;
&lt;P&gt;Normally we'd try to detect something like that so we could at least give a useful message to the user.&amp;nbsp; However, since 99% of our energy was focussed on Whidbey we simply couldn't spare the time for such niceties.&lt;/P&gt;
&lt;P&gt;Anyways, i hope you can get this stuff soon.&amp;nbsp; And when you do, let me know what you think!&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=486013" width="1" height="1"&gt;</content><author><name>CyrusN</name><uri>http://blogs.msdn.com/CyrusN/ProfileUrlRedirect.ashx</uri></author></entry><entry><title>PDC 2005 Videos Available</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/cyrusn/archive/2005/10/26/485035.aspx" /><id>http://blogs.msdn.com/b/cyrusn/archive/2005/10/26/485035.aspx</id><published>2005-10-26T10:10:00Z</published><updated>2005-10-26T10:10:00Z</updated><content type="html">&lt;P&gt;For all who missed it (like me), you can now see all the 2005 PDC sessions.&amp;nbsp; They're available here: &lt;A href="http://microsoft.sitestream.com/PDC05/"&gt;http://microsoft.sitestream.com/PDC05/&lt;/A&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Usually these are available for a while (but not indefinitely), so grab 'em while they're hot.&lt;/P&gt;
&lt;P&gt;Obviously i think you should check out the &lt;A href="http://microsoft.sitestream.com/PDC05/TLN/TLN306.htm#nopreload=1&amp;amp;autostart=1"&gt;Linq&lt;/A&gt; &lt;A href="http://microsoft.sitestream.com/PDC05/TLN/TLN307.htm#nopreload=1&amp;amp;autostart=1"&gt;videos&lt;/A&gt;, but i also recommend the &lt;A href="http://microsoft.sitestream.com/PDC05/TLN/TLN303.htm#nopreload=1&amp;amp;autostart=1"&gt;Monad&lt;/A&gt; video.&lt;/P&gt;
&lt;P&gt;Cheers!&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=485035" width="1" height="1"&gt;</content><author><name>CyrusN</name><uri>http://blogs.msdn.com/CyrusN/ProfileUrlRedirect.ashx</uri></author></entry><entry><title>Linq Specifiqs - var</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/cyrusn/archive/2005/09/28/474795.aspx" /><id>http://blogs.msdn.com/b/cyrusn/archive/2005/09/28/474795.aspx</id><published>2005-09-28T10:33:00Z</published><updated>2005-09-28T10:33:00Z</updated><content type="html">&lt;P&gt;So this is the start of a series of posts that will dive a little deeper into the new C# 3.0 features.&amp;nbsp; My &lt;a href="http://blogs.msdn.com/cyrusn/archive/2005/09/13/465390.aspx"&gt;previous&lt;/A&gt; &lt;a href="http://blogs.msdn.com/cyrusn/archive/2005/09/16/469953.aspx"&gt;posts&lt;/A&gt; covered an overall view of what we were doing with the language as well as the Linq initiative, but didn't delve deep into the nitty gritty behind everything.&amp;nbsp; Hopefully through these posts i can make each individual facet of the future work clearer.&amp;nbsp; I'll also bring up open questions we still have and my own personal thoughts on the where we are now and where i hope to be.&lt;/P&gt;
&lt;P&gt;It should be noted that what we have shown at the PDC is just a *preview*.&amp;nbsp; Nothing is set in stone, and it's quite likely that things will definitively change before the final future release.&amp;nbsp; It's my hope that by communicating with the developer community we can end up creating a better C# 3.0 for everyone.&lt;/P&gt;
&lt;P&gt;So, i'm going start with the "var" feature.&amp;nbsp; The full name is actually "Implicitly Typed Local Variables", but that's quite a mouthful, so we'll just be calling it the "var" feature for now.&amp;nbsp; So what is this feature?&amp;nbsp; Well, as the full name would imply, it's a feature that allows you to declare a local variable without having to explicitly declare its type.&amp;nbsp; For example, say you currently had the following code within some member:&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;&lt;PRE class=coloredcode&gt;&lt;SPAN class=kwd&gt;int&lt;/SPAN&gt; i = 5;
&lt;SPAN class=kwd&gt;string&lt;/SPAN&gt; s = &lt;SPAN class=st&gt;"Hello"&lt;/SPAN&gt;;
&lt;SPAN class=kwd&gt;double&lt;/SPAN&gt; d = 1.0;
&lt;SPAN class=kwd&gt;int&lt;/SPAN&gt;[] numbers = &lt;SPAN class=kwd&gt;new int&lt;/SPAN&gt;[] {1, 2, 3};
&lt;SPAN class=clss&gt;Dictionary&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=kwd&gt;int&lt;/SPAN&gt;,&lt;SPAN class=clss&gt;Order&lt;/SPAN&gt;&amp;gt; orders = &lt;SPAN class=kwd&gt;new&lt;/SPAN&gt; &lt;SPAN class=clss&gt;Dictionary&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=kwd&gt;int&lt;/SPAN&gt;,&lt;SPAN class=clss&gt;Order&lt;/SPAN&gt;&amp;gt;();
&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;You could now write that as:&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;&lt;PRE class=coloredcode&gt;&lt;SPAN class=kwd&gt;var&lt;/SPAN&gt; i = 5;
&lt;SPAN class=kwd&gt;var&lt;/SPAN&gt; s = &lt;SPAN class=st&gt;"Hello"&lt;/SPAN&gt;;
&lt;SPAN class=kwd&gt;var&lt;/SPAN&gt; d = 1.0;
&lt;SPAN class=kwd&gt;var&lt;/SPAN&gt; numbers = &lt;SPAN class=kwd&gt;new int&lt;/SPAN&gt;[] {1, 2, 3};
&lt;SPAN class=kwd&gt;var&lt;/SPAN&gt; orders = &lt;SPAN class=kwd&gt;new&lt;/SPAN&gt; &lt;SPAN class=clss&gt;Dictionary&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=kwd&gt;int&lt;/SPAN&gt;,&lt;SPAN class=clss&gt;Order&lt;/SPAN&gt;&amp;gt;();
&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;The important thing to realize is that "var" does *not* mean "object".&amp;nbsp; In fact, both code samples above will compile to the *exact* same thing.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;So how does this work?&amp;nbsp; Well, unlike a regular local variable declaration, a "var" declaration is required to have not just a name, but also an initializer as well.&amp;nbsp; The compiler will then figure out the type of the initializer expression (which is well defined as per the rules of the C# language) and treat the declaration as if you'd used that type as the local variable type.&amp;nbsp; So if you then try to type:&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;&lt;PRE class=coloredcode&gt;s.IndexOf(&lt;SPAN class=st&gt;'{'&lt;/SPAN&gt;); &lt;SPAN class=cmt&gt;//This will compile.  's' is a string, and string has an IndexOf(char) method on it.&lt;/SPAN&gt;
s.FoobyBoob(); &lt;SPAN class=cmt&gt;//This won't compile.  string doesn't have 'FoobyBoob' method&lt;/SPAN&gt;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;To make things clear.&amp;nbsp; "var" isn't some "variant" type (although the name is certainly unfortunate), and it doesn't imply some sort of "dynamic" typing system going on.&amp;nbsp; Your code is statically checked exactly as it would be if you had explicitly written down the type.&lt;/P&gt;
&lt;P&gt;Now, right now "var" is just for local variables.&amp;nbsp; Why not allow it for something like&amp;nbsp;a method parameter declaration?&amp;nbsp; Well, say you had the following:&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;&lt;PRE class=coloredcode&gt;&lt;SPAN class=kwd&gt;interface&lt;/SPAN&gt; IExample {
    &lt;SPAN class=kwd&gt;void&lt;/SPAN&gt; ShowOff(var parameter); &lt;SPAN class=cmt&gt;//what type would this be?  It has no initializer to determine the type from&lt;/SPAN&gt;
}

&lt;SPAN class=kwd&gt;class&lt;/SPAN&gt; OtherExample {
    &lt;SPAN class=kwd&gt;void&lt;/SPAN&gt; Demonstration(var parameter) { &lt;SPAN class=cmt&gt;//what type would this be?&lt;/SPAN&gt;
        parameter.Convert();            &lt;SPAN class=cmt&gt;//we can't figure out what type it should be based on what we see here.&lt;/SPAN&gt;
    }
}&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;In the first case, there's simply nothing we could do.&amp;nbsp; Without any sort of code in scope that uses "parameter" we couldn't hope to determine what its type was.&amp;nbsp; In the second case, it's possible we could try to figure out the type somehow, but it would probably be enormously complex and confusing (And often we'd still be unable to figure it out).&amp;nbsp; By limiting to local variables that *have* to have an initializer, we ensure a feature that will be usable and available in pretty all places where local variables are allowed..&lt;/P&gt;
&lt;P&gt;So... um... neat... but why would i want that? &lt;/P&gt;
&lt;P&gt;That's a fantastic question.&amp;nbsp; Let's start by referring to some shortcomings/negatives first.&amp;nbsp; While implicitness can be quite handy for writing code, it can make things quite difficult when trying to just read code.&amp;nbsp; In all the above examples it's fairly easy to determine what the type of each of the variables is.&amp;nbsp; That's because you have either a nice primitive that you can look at, or the call to some constructor which you can then look directly at to figure out the type of variable.&amp;nbsp; But it's not always that simple.&amp;nbsp; What if you were to have:&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;&lt;PRE class=coloredcode&gt;&lt;SPAN class=kwd&gt;var&lt;/SPAN&gt; lollerskates = GetSkates(these, parameters, will, affect, overload, resolution);&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Now what do you do?&amp;nbsp; As i said before the type of the variable will be statically determined by the compiler using the expression binding rules that are spelled out in detail in the C# specification.&amp;nbsp; But that in itself is an extraordinary problem.&amp;nbsp; There is a huge number of binding rules, and some of them (like generic type inference) are quite complex.&amp;nbsp; Keeping all those rules in your head and correctly trying to apply them on-the-fly in order to just comprehend what your code means sounds like a rather onerous burden to put on you.&amp;nbsp; In effect we'd be asking you to do the compilers job just so you could answer the question "is lollerskates an IEnumerable or an IList??"&lt;/P&gt;
&lt;P&gt;On the other hand, var does make other things nicer.&amp;nbsp; For one thing, it avoids some pretty ugly duplication that arises when you start to write heavily genericized code.&amp;nbsp; Instead of needing to write:&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;&lt;PRE class=coloredcode&gt;&lt;SPAN class=clss&gt;Dictionary&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=clss&gt;IOptional&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=clss&gt;IList&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=kwd&gt;string&lt;/SPAN&gt;&amp;gt;&amp;gt;,&lt;SPAN class=clss&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=clss&gt;ICollection&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=kwd&gt;int&lt;/SPAN&gt;&amp;gt;&amp;gt;&amp;gt; characterClasses = 
    &lt;SPAN class=kwd&gt;new&lt;/SPAN&gt; &lt;SPAN class=clss&gt;Dictionary&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=clss&gt;IOptional&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=clss&gt;IList&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=kwd&gt;string&lt;/SPAN&gt;&amp;gt;&amp;gt;,&lt;SPAN class=clss&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=clss&gt;ICollection&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=kwd&gt;int&lt;/SPAN&gt;&amp;gt;&amp;gt;&amp;gt;()&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;you can now write:&lt;/P&gt;
&lt;P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;&lt;PRE class=coloredcode&gt;&lt;SPAN class=kwd&gt;var&lt;/SPAN&gt; characterClasses = &lt;SPAN class=kwd&gt;new&lt;/SPAN&gt; &lt;SPAN class=clss&gt;Dictionary&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=clss&gt;IOptional&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=clss&gt;IList&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=kwd&gt;string&lt;/SPAN&gt;&amp;gt;&amp;gt;,&lt;SPAN class=clss&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=clss&gt;ICollection&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=kwd&gt;int&lt;/SPAN&gt;&amp;gt;&amp;gt;&amp;gt;()&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;There's a heck of a lot of duplication that you can now cut out.&amp;nbsp; It cleans up your code *and* makes it more readable (IMO).&amp;nbsp; Two plusses that are always welcome in my book.&amp;nbsp; Another benefit is if you have code like this:&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;&lt;PRE class=coloredcode&gt;&lt;SPAN class=kwd&gt;object&lt;/SPAN&gt; o = ExistingMethod();

...

&lt;SPAN class=kwd&gt;object&lt;/SPAN&gt; ExistingMethod() { ... }&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;If you then update ExistingMethod like so:&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;&lt;PRE class=coloredcode&gt;&lt;SPAN class=kwd&gt;string&lt;/SPAN&gt; ExistingMethod() { ... }&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Well, your code still compiles, however if you want to take advantage of the fact that ExistingMethod returns "string" (i.e. to call some method like IndexOf on them) you'll have to update all your declarations that call from "object" to "string".&amp;nbsp; If you had declared it as:&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;&lt;PRE class=coloredcode&gt;&lt;SPAN class=kwd&gt;var&lt;/SPAN&gt; o = ExistingMethod();&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;then you would only have to update one location while still being able to take advantage of that redefinition everywhere.&lt;/P&gt;
&lt;P&gt;Ok.&amp;nbsp; Well, those both seem somewhat *meh*'ish.&amp;nbsp; Convenient sure, but worth the potential negatives in code readability?&amp;nbsp; With C# 2.0 as it exists today... probably not.&amp;nbsp; But with some of the Linq work we have coming up, then the picture changes quite a bit.&amp;nbsp; Let's start by looking at a potential way you can write queries in C# 3.0:&lt;/P&gt;
&lt;P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;&lt;PRE class=coloredcode&gt;   &lt;SPAN class=kwd&gt;var &lt;/SPAN&gt;q = 
      &lt;SPAN class=kwd&gt;from &lt;/SPAN&gt;c &lt;SPAN class=kwd&gt;in&lt;/SPAN&gt; customers
      &lt;SPAN class=kwd&gt;where &lt;/SPAN&gt;c.City == &lt;SPAN class=st&gt;"Seattle"&lt;/SPAN&gt;
      &lt;SPAN class=kwd&gt;select &lt;/SPAN&gt;&lt;SPAN class=kwd&gt;new&lt;/SPAN&gt; {
          c.Name,
          Orders = 
              &lt;SPAN class=kwd&gt;from &lt;/SPAN&gt;o &lt;SPAN class=kwd&gt;in&lt;/SPAN&gt; c.Orders
              &lt;SPAN class=kwd&gt;where &lt;/SPAN&gt;o.Cost &amp;gt; 1000
              &lt;SPAN class=kwd&gt;select &lt;/SPAN&gt;&lt;SPAN class=kwd&gt;new&lt;/SPAN&gt; { o.Cost, o.Date }
      };&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;In this case we're generating a hierarchical anonymous type (which i'll go in depth on in a future article).&amp;nbsp; Say we didn't have "var", but we *did* have some hypothetical syntax for expressing an anonymous type.&amp;nbsp; We'd end up having to write the following:&lt;/P&gt;
&lt;P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;&lt;PRE class=coloredcode&gt;  &lt;SPAN class=clss&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=kwd&gt;class&lt;/SPAN&gt; { &lt;SPAN class=kwd&gt;string&lt;/SPAN&gt; Name; &lt;SPAN class=clss&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=kwd&gt;class&lt;/SPAN&gt; { &lt;SPAN class=kwd&gt;int&lt;/SPAN&gt; Cost; &lt;SPAN class=clss&gt;DateTime&lt;/SPAN&gt; Date }&amp;gt; Orders }&amp;gt; q =
      &lt;SPAN class=kwd&gt;from &lt;/SPAN&gt;c &lt;SPAN class=kwd&gt;in&lt;/SPAN&gt; customers 
      &lt;SPAN class=kwd&gt;where &lt;/SPAN&gt;c.City == &lt;SPAN class=st&gt;"Seattle"&lt;/SPAN&gt; 
      &lt;SPAN class=kwd&gt;select &lt;/SPAN&gt;&lt;SPAN class=kwd&gt;new&lt;/SPAN&gt; { 
          c.Name, 
          Orders = 
              &lt;SPAN class=kwd&gt;from &lt;/SPAN&gt;o &lt;SPAN class=kwd&gt;in&lt;/SPAN&gt; c.Orders 
              &lt;SPAN class=kwd&gt;where &lt;/SPAN&gt;o.Cost &amp;gt; 1000 
              &lt;SPAN class=kwd&gt;select &lt;/SPAN&gt;&lt;SPAN class=kwd&gt;new&lt;/SPAN&gt; { o.Cost, o.Date } 
      };&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;Good golly!&amp;nbsp; That's a lot to type!&amp;nbsp; As with the "Dictionary" example above, you end up with a declaration with a lot of duplication in it.&amp;nbsp; Why should i have to fully declare this hierarchical type when the structure of the type i'm creating is fairly clear from the query initializing it.&amp;nbsp; You could make things easier for yourself by defining your own types ahead of time instead of using anonymous types, but that would make the act of projecting in a query far less simple than what you can do with anonymous types.&amp;nbsp;&amp;nbsp; Of course, if you want to do this, you're completely able to do so while being fully able to work within Linq system.&amp;nbsp; And, because this seems like a feature with it's own plusses/minuses, and because it seems like people will want to move back and forth between implicit/explicit types depending on the code they're writing, it will make a lot of sense for us to provide user tools for this space.&amp;nbsp; Some sort of refactoring like "Reify variables".&amp;nbsp; Or... since people won't know what the heck that means: "make variable implicit/explicit."&amp;nbsp;&amp;nbsp; :-)&lt;/P&gt;
&lt;P&gt;So what do you think?&amp;nbsp; Are there things you do/don't like about "var"?&amp;nbsp; Personally, i think the name is somewhat of a problem.&amp;nbsp; C++ is introducing a similar concept, while calling it "auto".&amp;nbsp; I'm partial to that, but leaning more to making "infer" a keyword itself.&amp;nbsp; I think writing down "infer a = "5" reads very well and helps alleviate confusion issues that might arise with "var".&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=474795" width="1" height="1"&gt;</content><author><name>CyrusN</name><uri>http://blogs.msdn.com/CyrusN/ProfileUrlRedirect.ashx</uri></author></entry><entry><title>Problems with my Blog</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/cyrusn/archive/2005/09/21/472381.aspx" /><id>http://blogs.msdn.com/b/cyrusn/archive/2005/09/21/472381.aspx</id><published>2005-09-21T19:50:00Z</published><updated>2005-09-21T19:50:00Z</updated><content type="html">&lt;P&gt;FYI: There seems to be a problem with the blog software i'm using where i'm not getting notified about all posts that you guys are making.&amp;nbsp; It's being actively investigated, and i'm hoping for a resolution soon.&amp;nbsp; So if you're finding that i'm not responding to a post in a timely manner (say a few days max), then feel free to directly reach me through the &lt;a href="http://blogs.msdn.com/cyrusn/contact.aspx"&gt;Contact&lt;/A&gt; link at the top of the page.&lt;/P&gt;
&lt;P&gt;Sorry for all this.&amp;nbsp; And please don't think that i'm ignoring you or your questions!&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=472381" width="1" height="1"&gt;</content><author><name>CyrusN</name><uri>http://blogs.msdn.com/CyrusN/ProfileUrlRedirect.ashx</uri></author></entry><entry><title>So what's the deal with this whole C# 3.0 / Linq thingy? (Part 2)</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/cyrusn/archive/2005/09/16/469953.aspx" /><id>http://blogs.msdn.com/b/cyrusn/archive/2005/09/16/469953.aspx</id><published>2005-09-17T05:53:00Z</published><updated>2005-09-17T05:53:00Z</updated><content type="html">&lt;P&gt;In the &lt;a href="http://blogs.msdn.com/cyrusn/archive/2005/09/13/465390.aspx"&gt;last post&lt;/A&gt; i&amp;nbsp; discussed a little bit of background on why we wanted to introduce Linq, as well as a bit of info on what some basic C# Linq looked like.&amp;nbsp; In this post i'm going to dive in a little bit deeper to some other interesting things we're introducing as well&lt;/P&gt;
&lt;P&gt;Here's the current example we've been using to drive the discussion along&lt;/P&gt;&lt;PRE class=coloredcode&gt;        &lt;SPAN class=clss&gt;Customer&lt;/SPAN&gt;[] customers = GetCustomers();
        &lt;SPAN class=kwd&gt;var &lt;/SPAN&gt;custs = customers.Where(c =&amp;gt; c.City == &lt;SPAN class=st&gt;"Seattle"&lt;/SPAN&gt;).Select(c =&amp;gt; c.Name);&lt;/PRE&gt;
&lt;P&gt;Now, so far that's a very C#-centric way to do queries over data.&amp;nbsp; However, it's still a little bit heavyweight.&amp;nbsp; What about a more query-like syntax to do the same that's far more convenient?&amp;nbsp; Well, it turns out htat we have that as well:&lt;/P&gt;&lt;PRE class=coloredcode&gt;   &lt;SPAN class=kwd&gt;var &lt;/SPAN&gt;q = 
      &lt;SPAN class=kwd&gt;from &lt;/SPAN&gt;c &lt;SPAN class=kwd&gt;in&lt;/SPAN&gt; customers
      &lt;SPAN class=kwd&gt;where &lt;/SPAN&gt;c.City == &lt;SPAN class=st&gt;"Seattle"&lt;/SPAN&gt;
      &lt;SPAN class=kwd&gt;select &lt;/SPAN&gt;c.Name;&lt;/PRE&gt;
&lt;P&gt;This new query syntax is in fact just syntactic sugar that uses patterns to transform itself into the *exact* same C# query that i listed above.&amp;nbsp; In fact, this is the same way that we handle foreach&amp;nbsp;(specifically by transforming it into a loop with calls to MoveNext, Current, Dispose).&lt;/P&gt;
&lt;P&gt;Now, when looking at this you'll almost certainly notice how it looks *almost*, but not quite like SQL.&amp;nbsp; And, you'll probably be asking: "can't you just make it look like SQL if it's that close!&amp;nbsp; Is this just MS wanting to be a pain just for the heck of it??"&amp;nbsp; In this case, the answer is "No".&amp;nbsp; One of hte problems with the straight SQL like approach is that we'd have to put the "select" first.&amp;nbsp; "Ok... what's wrong with that" you say.&amp;nbsp;&amp;nbsp; Well, let's take a look:&lt;/P&gt;&lt;PRE class=coloredcode&gt;   &lt;SPAN class=kwd&gt;var &lt;/SPAN&gt;q = 
      &lt;SPAN class=kwd&gt;select &lt;/SPAN&gt;c&amp;lt;dot&amp;gt;&lt;/PRE&gt;
&lt;P&gt;Now, at this point, you're constructing the final shape for this query.&amp;nbsp; You know you want to write "c.Name" and you'd like to utilize handy features like IntelliSense to help speed you up with typing that.&amp;nbsp; But you can't!&amp;nbsp; Because you haven't even stated where your data is coming from, there's no way to understand what's going on this early in the expression.&amp;nbsp; This is because in SQL the scope of a variable actually flows backwards.&amp;nbsp; i.e. you use variables before you've even declared this.&amp;nbsp; However, in C# you can only use something after it's been declared.&amp;nbsp; So in order to better fit within this model (which has some very nice benefits), we made it so that from has to come first.&amp;nbsp; Beyond statement completion there are also issues of being able to construct large hierarchical queries in an understandable way.&amp;nbsp; Having the scope flow from left to right, top to bottom, makes that much simpler and brings a lot of clarity to your expressions.&lt;/P&gt;
&lt;P&gt;Now what about projections?&amp;nbsp; They're incredibly common operations in SQL.&amp;nbsp; You're aways doing things like "select a, b, c" and in essence projection out the information you care about into these columns.&amp;nbsp; So how would we go about doing this sort of thing in C# 3.0?&amp;nbsp; Well, you could do this:&lt;/P&gt;&lt;PRE class=coloredcode&gt;   &lt;SPAN class=kwd&gt;var &lt;/SPAN&gt;q = 
      &lt;SPAN class=kwd&gt;from &lt;/SPAN&gt;c &lt;SPAN class=kwd&gt;in&lt;/SPAN&gt; customers
      &lt;SPAN class=kwd&gt;where &lt;/SPAN&gt;c.City == &lt;SPAN class=st&gt;"Seattle"&lt;/SPAN&gt;
      &lt;SPAN class=kwd&gt;select &lt;/SPAN&gt;&lt;SPAN class=kwd&gt;new&lt;/SPAN&gt; &lt;SPAN class=clss&gt;NameAndAge&lt;/SPAN&gt;(c.Name, c.Age);&lt;/PRE&gt;
&lt;P&gt;but that's a real pain.&amp;nbsp; Any time i want to project any information out, i need to generate a new type and fill all it's gunk in.&amp;nbsp; That means writing the class somewhere.&amp;nbsp; Creating a constructor for it.&amp;nbsp; Creating fields and properties.&amp;nbsp; Implementing .Equals and .GetHashCode.&amp;nbsp; etc. etc.&amp;nbsp; yech.&amp;nbsp; Far too much work, error prone and causes API clutter.&amp;nbsp; So what can we do to alleviate that?&amp;nbsp; Well, in C# 3.0 a new feature called "Anonymous Types" comes to the rescue.&amp;nbsp; We can now write the following:&lt;/P&gt;&lt;PRE class=coloredcode&gt;   &lt;SPAN class=kwd&gt;var &lt;/SPAN&gt;q = 
      &lt;SPAN class=kwd&gt;from &lt;/SPAN&gt;c &lt;SPAN class=kwd&gt;in&lt;/SPAN&gt; customers
      &lt;SPAN class=kwd&gt;where &lt;/SPAN&gt;c.City == &lt;SPAN class=st&gt;"Seattle"&lt;/SPAN&gt;
      &lt;SPAN class=kwd&gt;select &lt;/SPAN&gt;&lt;SPAN class=kwd&gt;new&lt;/SPAN&gt; { c.Name, c.Age };&lt;/PRE&gt;
&lt;P&gt;What this is doing is projecting the customer out into a new structural type with two properties "Name" and "Age", both of which are strongly typed and which have been assigned the values of their corresponding properties in "c".&amp;nbsp; What's the type of Q at this point?&amp;nbsp; Well, it's an IEnumerable&amp;lt;???&amp;gt; where ??? is some anonymous type with those two properties on it.&amp;nbsp; BTW, it should now seem somewhat more obvious why the "var" keyword was added to the language.&amp;nbsp; In this case you cannot actually write down the type of "q", but you need some way to declare it.&amp;nbsp; "var" comes to the rescue here.&lt;/P&gt;
&lt;P&gt;So i could now write:&lt;/P&gt;&lt;PRE class=coloredcode&gt;   &lt;SPAN class=kwd&gt;foreach&lt;/SPAN&gt; (&lt;SPAN class=kwd&gt;var &lt;/SPAN&gt;c &lt;SPAN class=kwd&gt;in&lt;/SPAN&gt; q) {
      &lt;SPAN class=clss&gt;Console&lt;/SPAN&gt;.WriteLine(c.Name);
   }&lt;/PRE&gt;
&lt;P&gt;and that would compile and run just file.&lt;/P&gt;
&lt;P&gt;Now "wait a minute!" you're saying.&amp;nbsp; "Is this some sort of late-binding thang where we're using refelction to pull out this data?"&amp;nbsp; No sir-ee.&amp;nbsp; In fact, if you were to try and write:&lt;/P&gt;&lt;PRE class=coloredcode&gt;   &lt;SPAN class=kwd&gt;foreach&lt;/SPAN&gt; (&lt;SPAN class=kwd&gt;var &lt;/SPAN&gt;c &lt;SPAN class=kwd&gt;in&lt;/SPAN&gt; q) {
      &lt;SPAN class=clss&gt;Console&lt;/SPAN&gt;.WriteLine(c.Company);
   }&lt;/PRE&gt;
&lt;P&gt;then you would get a compiler error immediate.&amp;nbsp; Why?&amp;nbsp; Well, the compiler knows that the anonymous type which you've instantiated only has two members on it (Name and Age), and it's able to flow that information into the type signature of 'q'.&amp;nbsp; Then when foreach'ing over 'q', it knows that the type of 'c' is the same structural anonymous type we created earlier in the 'select'.&amp;nbsp; So it will know that it has no "Company" property and appropriately inform you that your code is bogus.&amp;nbsp; All the strong, static typeing of C# is there.&amp;nbsp; You are just allowed to exchew writing the type now and instead allow inference to to take care of all of it for you.&amp;nbsp; Users of languages like OCaml will find this immeditely familiar and comfortable.&lt;/P&gt;
&lt;P&gt;Now, one thing that's quite common in the object world is the usage and manipulation of hierarchical data.&amp;nbsp; i.e. objects formed by collection of other objects formed by collections of... you get the idea.&amp;nbsp; Now, say you wanted to query your customers to get not only the customer name, but information about the orders they've been creating.&amp;nbsp; You could write the following very SQL-esque query:&lt;/P&gt;&lt;PRE class=coloredcode&gt;&lt;PRE class=coloredcode&gt;   &lt;SPAN class=kwd&gt;var &lt;/SPAN&gt;q = 
      &lt;SPAN class=kwd&gt;from &lt;/SPAN&gt;c &lt;SPAN class=kwd&gt;in&lt;/SPAN&gt; customers
      &lt;SPAN class=kwd&gt;where &lt;/SPAN&gt;c.City == &lt;SPAN class=st&gt;"Seattle"&lt;/SPAN&gt;
      &lt;SPAN class=kwd&gt;from &lt;/SPAN&gt;o &lt;SPAN class=kwd&gt;in&lt;/SPAN&gt; c.Orders 
      &lt;SPAN class=kwd&gt;where &lt;/SPAN&gt;o.Cost &amp;gt; 1000
      &lt;SPAN class=kwd&gt;select &lt;/SPAN&gt;&lt;SPAN class=kwd&gt;new&lt;/SPAN&gt; { c.Name, o.Cost, o.Date };&lt;/PRE&gt;&lt;/PRE&gt;
&lt;P&gt;We've now joined the customer with their own orders.&amp;nbsp; This would get the job done, but maybe it's not really returning the information in the structure you want.&amp;nbsp; For one thing, the data isn't grouped by customer.&amp;nbsp; So for every order made by the same customer you're going to get a new element.&amp;nbsp; So let's take it a little further:&lt;/P&gt;&lt;PRE class=coloredcode&gt;   &lt;SPAN class=kwd&gt;var &lt;/SPAN&gt;q = 
      &lt;SPAN class=kwd&gt;from &lt;/SPAN&gt;c &lt;SPAN class=kwd&gt;in&lt;/SPAN&gt; customers
      &lt;SPAN class=kwd&gt;where &lt;/SPAN&gt;c.City == &lt;SPAN class=st&gt;"Seattle"&lt;/SPAN&gt;
      &lt;SPAN class=kwd&gt;select &lt;/SPAN&gt;&lt;SPAN class=kwd&gt;new&lt;/SPAN&gt; {
          c.Name,
          Orders = 
              &lt;SPAN class=kwd&gt;from &lt;/SPAN&gt;o &lt;SPAN class=kwd&gt;in&lt;/SPAN&gt; c.Orders
              &lt;SPAN class=kwd&gt;where &lt;/SPAN&gt;o.Cost &amp;gt; 1000
              &lt;SPAN class=kwd&gt;select &lt;/SPAN&gt;&lt;SPAN class=kwd&gt;new&lt;/SPAN&gt; { o.Cost, o.Date }
      };&lt;/PRE&gt;
&lt;P&gt;Voila.&amp;nbsp; We've now created a hierarchical result.&amp;nbsp; Now, per customer you'll only get one item returned.&amp;nbsp; And that item will have information about all the different orders they've made that fit your criteria.&amp;nbsp; Now you can trivially create queries that get you the results you want in the exact shape you want.&lt;/P&gt;
&lt;P&gt;Next up!&amp;nbsp; Drill downs into many of the specific new features that we're bringing to the table.&lt;/P&gt;
&lt;P&gt;But first: a teaser!&amp;nbsp; Say you have the following code:&lt;/P&gt;&lt;PRE class=coloredcode&gt;   &lt;SPAN class=kwd&gt;var &lt;/SPAN&gt;customers = GetCustomersFromDataBase();
   &lt;SPAN class=kwd&gt;var &lt;/SPAN&gt;q = 
      &lt;SPAN class=kwd&gt;from &lt;/SPAN&gt;c &lt;SPAN class=kwd&gt;in&lt;/SPAN&gt; customers
      &lt;SPAN class=kwd&gt;where &lt;/SPAN&gt;c.City == &lt;SPAN class=st&gt;"Seattle"&lt;/SPAN&gt;
      &lt;SPAN class=kwd&gt;select &lt;/SPAN&gt;&lt;SPAN class=kwd&gt;new&lt;/SPAN&gt; {
          c.Name,
          Orders = 
              &lt;SPAN class=kwd&gt;from &lt;/SPAN&gt;o &lt;SPAN class=kwd&gt;in&lt;/SPAN&gt; c.Orders
              &lt;SPAN class=kwd&gt;where &lt;/SPAN&gt;o.Cost &amp;gt; 1000
              &lt;SPAN class=kwd&gt;select &lt;/SPAN&gt;&lt;SPAN class=kwd&gt;new&lt;/SPAN&gt; { o.Cost, o.Date }
      };

   &lt;SPAN class=kwd&gt;foreach&lt;/SPAN&gt; (&lt;SPAN class=kwd&gt;var &lt;/SPAN&gt;c &lt;SPAN class=kwd&gt;in&lt;/SPAN&gt; q) {
       &lt;SPAN class=cmt&gt;//Do something with c&lt;/SPAN&gt;
   }&lt;/PRE&gt;
&lt;P&gt;Did you know that you will be able to write that code in C# 3.0 and DLinq will make sure that that query executes on the DB using SQL?&amp;nbsp; It will then only suck down the results that matched the query, and only when you foreach over them.&amp;nbsp;&amp;nbsp; That's right.&amp;nbsp; That entire "from ... " expression will execure server side.&amp;nbsp; And it didn't need to even be in "from" form.&amp;nbsp; If you'd written it as "&lt;FONT face="Courier New" color=#000000 size=2&gt;customers.Where(c =&amp;gt; c.City == &lt;SPAN class=st&gt;"Seattle"&lt;/SPAN&gt;).Select(c =&amp;gt; c.Name)&lt;/FONT&gt;" then the same&amp;nbsp; would be true.&amp;nbsp; How's that for cool.&amp;nbsp; Stay tuned and a later post will tell you how that all works!&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=469953" width="1" height="1"&gt;</content><author><name>CyrusN</name><uri>http://blogs.msdn.com/CyrusN/ProfileUrlRedirect.ashx</uri></author></entry><entry><title>So what's the deal with this whole C# 3.0 / Linq thingy?</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/cyrusn/archive/2005/09/13/465390.aspx" /><id>http://blogs.msdn.com/b/cyrusn/archive/2005/09/13/465390.aspx</id><published>2005-09-14T06:31:00Z</published><updated>2005-09-14T06:31:00Z</updated><content type="html">&lt;P&gt;I've been mulling over the best way to talk about the new C# 3.0 stuff we've been working on.&amp;nbsp; I presented the post on how you could use the new C# 3.0 features to go beyond the basic query functionality we've been targetting it at.&amp;nbsp; The was to help give an appreciation about how we've added strong query support through the addition of several new smaller features that can be used for more than query (although that's the formost area that we're trying to attack).&amp;nbsp; However, i then realized that it was somewhat interesting that i would present the post on "what *else* you can do with C# 3.0" before anyone even had idea of what you "could" did with C# 3.0 first.&lt;/P&gt;
&lt;P&gt;I could do a fairly detailed drill down of the new C# features, but i actually thought a more holistic approach would be better in this case.&amp;nbsp; So i'm actually going to talk about the general problem space we're confronting, and i'll try to provide some running examples to help carry me through this.&lt;/P&gt;
&lt;P&gt;So what is Linq?&amp;nbsp; Well, Linq is the culmination of a number of techniques we're producing to help deal with the large disconnect between data programming and general purpose programming languages. Linq stands for Language INtegrated Query, and simply put, it's about taking query, set operations and transforms and making them first class concepts in the .Net world.&amp;nbsp; This means making them available in the CLR, in .Net programming languages, and in the APIs that you're going to be using to program against data in the future.&amp;nbsp; Through all this you can get a completely unified query experience against&amp;nbsp;objects, XML, and relational data.&amp;nbsp; i.e. the most common forms of data that will appear in your application.&amp;nbsp; And, what's best, if you happen to have your own form of data that doesn't fit into those different models, then you can use our extensible system to target that model as well.&amp;nbsp; After all, our XML and relational data access models (called XLinq and DLinq respectively) are just APIs built on top of the core Linq infrastructure.&amp;nbsp; As such, i'm not going to dive too deeply into those specific models.&amp;nbsp; I'm going to let the individual teams who are responsible for that (and who know those APIs far more intimately) to give you all the information at their disposal.&lt;/P&gt;
&lt;P&gt;So, let's first talk about data access today and how our new approach most likely differs from that you've been used to.&amp;nbsp; If you're accessing a database somewhere in your application, then there's a good chance that you've embedded some bit of SQL somewhere.&amp;nbsp; Maybe you've kept it fairly clean and abstracted away, or maybe you have SqlCommand's left rigth and center all with their own "select *"'s or other raw SQL commands stored hither.&amp;nbsp; Of course, when writing this code you had no compile time checking that your SQL strings were well formed, no IntelliSense, etc.&amp;nbsp; Because, effectively, you are using two completely different languages in an environment that only understands one.&amp;nbsp; This is pretty bad, but really only begins to scratch the surface of the deep mismatch between this relational data domain and the object domain.&lt;/P&gt;
&lt;P&gt;Through and through you have mismatches between objects and relational data and XML in your system.&amp;nbsp; Different types.&amp;nbsp; Different operations.&amp;nbsp; Different programming models.&amp;nbsp; Your code which works on XML won't work on relational data.&amp;nbsp; You code which works on relational won't work on objects. etc.&amp;nbsp; But there's a better way.&amp;nbsp; Now we can allow you to work with all these different data systems right within C# (or VB).&amp;nbsp; This means using the same syntax, the same types, and the same programm ing models to query and manipulate all these different forms of data in a unified manner.&amp;nbsp; And, because support for these models has been built on top of an extensible system, it means that if necessary you can do the same as what we've done to bring this strong query support anywhere you need to it go where we don't currently have an offerring.&lt;/P&gt;
&lt;P&gt;To ground this discussion a little, let's start looking at a simple example of C# 3.0/Linq in action.&amp;nbsp; (Note: this example might look very familiar.&amp;nbsp; That's because many demos and examples are made to run against the Northwind DB.&amp;nbsp; This allows us to all talk about the same thing and have consistent and clear names for entities).&amp;nbsp;&amp;nbsp; You start with a simple list of Customers:&lt;/P&gt;&lt;PRE class=coloredcode&gt;        &lt;SPAN class=clss&gt;Customer&lt;/SPAN&gt;[] customers = GetCustomers();&lt;/PRE&gt;
&lt;P&gt;Nothing magic going on here.&amp;nbsp; Nothing up my sleaves.&amp;nbsp;&amp;nbsp; Just a regular .Net array initialized from some source.&amp;nbsp; Now, to make things a little simpler (especially for later examples) we can then write that as:&lt;/P&gt;&lt;PRE class=coloredcode&gt;        &lt;SPAN class=clss&gt;Customer&lt;/SPAN&gt;[] customers = GetCustomers();
        &lt;SPAN class=kwd&gt;var&lt;/SPAN&gt; custs = customers;&lt;/PRE&gt;
&lt;P&gt;What's going on in that second line? Well, "var" is are way of introducing "local variable type inference".&amp;nbsp; It's a new C# 3.0 feature that allows you to save space by not writing the type of a local variable, while also having the type inferred from the expression that initializes the variable.&amp;nbsp; So, in the above code, "custs" is known at compile time to be a "&lt;SPAN class=clss&gt;Customer&lt;/SPAN&gt;[]".&amp;nbsp; If you were to write: &lt;/P&gt;&lt;PRE class=coloredcode&gt;        &lt;SPAN class=kwd&gt;var&lt;/SPAN&gt; i = 10;
        &lt;SPAN class=kwd&gt;var&lt;/SPAN&gt; b = &lt;SPAN class=kwd&gt;true&lt;/SPAN&gt;;
        &lt;SPAN class=kwd&gt;var&lt;/SPAN&gt; s = &lt;SPAN class=st&gt;"hello"&lt;/SPAN&gt;;&lt;/PRE&gt;
&lt;P&gt;then it would be the *exact* same as writing:&lt;/P&gt;&lt;PRE class=coloredcode&gt;        &lt;SPAN class=kwd&gt;int&lt;/SPAN&gt;    i = 10;
        &lt;SPAN class=kwd&gt;bool&lt;/SPAN&gt;   b = &lt;SPAN class=kwd&gt;true&lt;/SPAN&gt;;
        &lt;SPAN class=kwd&gt;string&lt;/SPAN&gt; s = &lt;SPAN class=st&gt;"hello"&lt;/SPAN&gt;;&lt;/PRE&gt;
&lt;P&gt;We'll see later on why this can be quite a handy thing.&amp;nbsp; Now, let's extend our code a bit further to start querying that array of customers:&lt;/P&gt;&lt;PRE class=coloredcode&gt;        &lt;SPAN class=clss&gt;Customer&lt;/SPAN&gt;[] customers = GetCustomers();
        &lt;SPAN class=kwd&gt;var&lt;/SPAN&gt; custs = customers.Where(c =&amp;gt; c.City == &lt;SPAN class=st&gt;"Seattle"&lt;/SPAN&gt;);&lt;/PRE&gt;
&lt;P&gt;Here we're simplying querying all our customers for the set of customers that are from Seattle.&amp;nbsp; And "custs" will be an &lt;SPAN class=clss&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=clss&gt;Customer&lt;/SPAN&gt;&amp;gt;.&amp;nbsp; We can even carry that a little further in to the following query:&lt;/P&gt;&lt;PRE class=coloredcode&gt;        &lt;SPAN class=clss&gt;Customer&lt;/SPAN&gt;[] customers = GetCustomers();
        &lt;SPAN class=kwd&gt;var&lt;/SPAN&gt; custs = customers.Where(c =&amp;gt; c.City == &lt;SPAN class=st&gt;"Seattle"&lt;/SPAN&gt;).Select(c =&amp;gt; c.Name);&lt;/PRE&gt;
&lt;P&gt;Here we're projecting out the name of all our customers from Seattle.&amp;nbsp;&amp;nbsp; So custs will be an IEnumerable&amp;lt;string&amp;gt;.&amp;nbsp; Now, what the heck is this code.&amp;nbsp; This isn't your daddy's C# anymore.&amp;nbsp; What are those funky arrows?&amp;nbsp; And where did the "Where" and "Select" methods come from??&amp;nbsp; They're certainly don't seem to be defined on array type when i look at it in ILDasm!&amp;nbsp; Well, to answer the first question, the funky =&amp;gt; arrow the new C# 3.0 syntax that allows you to create a lambda expression. You can think of a lambda expression as a natural evolution of the anonymous methods introduced in C# 2.0.&amp;nbsp; Lambda expressions benefit from simpler syntax and the ability to use inference.&amp;nbsp; So now you can write: &lt;/P&gt;&lt;PRE class=coloredcode&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; c =&amp;gt; c.City == &lt;SPAN class=st&gt;"Seattle"&lt;/SPAN&gt;&amp;nbsp; &lt;SPAN class=cmt&gt;//instead of&lt;/SPAN&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN class=kwd&gt;delegate&lt;/SPAN&gt; (&lt;SPAN class=clss&gt;Customer&lt;/SPAN&gt; c) { &lt;SPAN class=kwd&gt;return&lt;/SPAN&gt; c.City == &lt;SPAN class=st&gt;"Seattle"&lt;/SPAN&gt;; }&lt;/PRE&gt;
&lt;P&gt;As you can see, the C# 2.0 method just drowns you in syntax and it makes it&amp;nbsp;a rather poor choice to use in queries (heck!&amp;nbsp;there's a 2x increase in query size between the two).&amp;nbsp; However, the new C# lambda expression succitly encapsulates the test we want to perform, with only about 5 characters overhead.&lt;/P&gt;
&lt;P&gt;That answers the first question, but what about the second?&amp;nbsp; Where, oh where did "Where" come from?&amp;nbsp; This is an example of another new C# 3.0 feature we call "extension methods".&amp;nbsp; Extensions are a way to allow you to add operations to existing types that aren't under your control.&amp;nbsp; While that may give you the heebie-jeebies, rest assured, you're not actually modifying the actual type.&amp;nbsp; Rather, you're being allowed to use succint syntax to in effect execute a method as if it existed on this type.&amp;nbsp; Specifically, extension methods are static methods that look like so:&lt;/P&gt;&lt;PRE class=coloredcode&gt;&lt;SPAN class=kwd&gt;namespace&lt;/SPAN&gt; System.Query {
    &lt;SPAN class=kwd&gt;public static class&lt;/SPAN&gt; &lt;SPAN class=clss&gt;Sequence&lt;/SPAN&gt; {
        &lt;SPAN class=kwd&gt;public static&lt;/SPAN&gt; &lt;SPAN class=clss&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;T&amp;gt; Where&amp;lt;T&amp;gt;(&lt;SPAN class=kwd&gt;this&lt;/SPAN&gt; &lt;SPAN class=clss&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;T&amp;gt; e, &lt;SPAN class=clss&gt;Predicate&lt;/SPAN&gt;&amp;lt;T&amp;gt; p) {
            &lt;SPAN class=kwd&gt;foreach&lt;/SPAN&gt; (T t &lt;SPAN class=kwd&gt;in&lt;/SPAN&gt; e) {
                &lt;SPAN class=kwd&gt;if&lt;/SPAN&gt; (p(t)) {
                    yield &lt;SPAN class=kwd&gt;return&lt;/SPAN&gt; t;
                }
            }
        }
    }
}&lt;/PRE&gt;
&lt;P&gt;This declares an "extension method" on the IEnumerable&amp;lt;T&amp;gt; type.&amp;nbsp; When you import the namespace by writing "using System.Query", you now gain the ability to call teh "Where" method on anything that implements IEnumerable&amp;lt;T&amp;gt; (like Arrays).&amp;nbsp; With these extension methods we can now compose powerful query functions together to manipulate data easy.&lt;/P&gt;
&lt;P&gt;So at this point we've seen three new C# 3.0 features that can be used together to build a powerful base for querying objects.&amp;nbsp; In future posts i'll include information about the rest of the new language features, and i'll give a more comprehensive view of how sophisticated our query support is.&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=465390" width="1" height="1"&gt;</content><author><name>CyrusN</name><uri>http://blogs.msdn.com/CyrusN/ProfileUrlRedirect.ashx</uri></author></entry><entry><title>The future track of the C# language</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/cyrusn/archive/2005/09/13/465255.aspx" /><id>http://blogs.msdn.com/b/cyrusn/archive/2005/09/13/465255.aspx</id><published>2005-09-14T04:05:00Z</published><updated>2005-09-14T04:05:00Z</updated><content type="html">If you've heard about the new C#/Linq work that got announced today, but don't know where to go to find it.&amp;nbsp; Well, the awesome folks at MSDN have put up a &lt;A href="http://msdn.microsoft.com/vcsharp/future/"&gt;great page&lt;/A&gt; that highlights what we're working on, as well as providing great links to our latest specs as well as awesome videos that show off what this is all about.&amp;nbsp; In th enext few days i'll start going over this information in depth to give you an idea of what all the pieces are and how they all fit together.&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=465255" width="1" height="1"&gt;</content><author><name>CyrusN</name><uri>http://blogs.msdn.com/CyrusN/ProfileUrlRedirect.ashx</uri></author></entry><entry><title>C# 3.0 Language Enhancements Chat! (9/22/05 1-2pm PST)</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/cyrusn/archive/2005/09/13/464703.aspx" /><id>http://blogs.msdn.com/b/cyrusn/archive/2005/09/13/464703.aspx</id><published>2005-09-13T16:47:00Z</published><updated>2005-09-13T16:47:00Z</updated><content type="html">&lt;P&gt;Can’t attend PDC but still want to talk to the C# team about what's coming up? This chat is your chance! Join the C# team to discuss the newly announced C# 3.0 features like:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;extension methods&lt;/LI&gt;
&lt;LI&gt;lambda expressions&lt;/LI&gt;
&lt;LI&gt;type inference&lt;/LI&gt;
&lt;LI&gt;anonymous types &lt;/LI&gt;
&lt;LI&gt;query comprehensions&lt;/LI&gt;
&lt;LI&gt;Expression trees&lt;/LI&gt;
&lt;LI&gt;and the rest of the .NET Language Integrated Query Framework. &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;You've been hearing rumblings about this for a while, now we finally talk in depth about the future of the C# language.&amp;nbsp; Hope to see a lot of you there.&amp;nbsp; Current ETA is 9/22/05 at 1-2pm.&amp;nbsp; But check the main &lt;A href="http://msdn.microsoft.com/chats/#05_0922_MSDN_CL"&gt;link&amp;nbsp;to MSDN&lt;/A&gt; for more details and to track this on your calendar!&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=464703" width="1" height="1"&gt;</content><author><name>CyrusN</name><uri>http://blogs.msdn.com/CyrusN/ProfileUrlRedirect.ashx</uri></author></entry><entry><title>Only a few hours left (part 5)</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/cyrusn/archive/2005/09/13/464668.aspx" /><id>http://blogs.msdn.com/b/cyrusn/archive/2005/09/13/464668.aspx</id><published>2005-09-13T14:40:00Z</published><updated>2005-09-13T14:40:00Z</updated><content type="html">&lt;P&gt;The &lt;a href="http://blogs.msdn.com/cyrusn/archive/2005/09/13/464637.aspx"&gt;previous post&lt;/A&gt; ended up showing that while visitors are available in C#, they lack usability brought by built in language constructs they could have that would make them an ideal choice to solve our problem.&amp;nbsp; In Java, we saw that anonymous inner classes provided such a convenient construct, and in this post i wanted to show how several of the future language enhancements we're bringing to C# will also make this convenient usage possible.&amp;nbsp; Now, from what you've seen from PDC so far, the new &lt;A href="http://msdn.microsoft.com/netframework/future/linq"&gt;Linq&lt;/A&gt; enhancements are targetted all around object, data, and xml querying and manipulation.&amp;nbsp; However, as this post will show, the core functionality we've added to C# can be used for far more than just that.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Specifically, we're going to make use of two of the new core language features: Lambda Expressions and Object Initializers.&amp;nbsp; Let's take a look at how we could use those two features to make visitors far more enjoyable.&amp;nbsp;&amp;nbsp;To begin with, we're going to define our visitor interface and DefaultTokenVisitor slightly differently than how we did in Java.&amp;nbsp; In C# they're now going to look like this:&lt;/P&gt;&lt;PRE class=coloredcode&gt;    &lt;SPAN class=kwd&gt;public delegate void&lt;/SPAN&gt; &lt;SPAN class=clss&gt;Action&lt;/SPAN&gt;&amp;lt;A&amp;gt;(A a);

    &lt;SPAN class=kwd&gt;public interface&lt;/SPAN&gt; &lt;SPAN class=clss&gt;ITokenVisitor&lt;/SPAN&gt;
    {
        &lt;SPAN class=clss&gt;Action&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=clss&gt;Token&lt;/SPAN&gt;&amp;gt;                  VisitToken                  { &lt;SPAN class=kwd&gt;get&lt;/SPAN&gt;; &lt;SPAN class=kwd&gt;set&lt;/SPAN&gt;; }
        &lt;SPAN class=clss&gt;Action&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=clss&gt;KeywordToken&lt;/SPAN&gt;&amp;gt;           VisitKeywordToken           { &lt;SPAN class=kwd&gt;get&lt;/SPAN&gt;; &lt;SPAN class=kwd&gt;set&lt;/SPAN&gt;; }
        &lt;SPAN class=clss&gt;Action&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=clss&gt;InterfaceToken&lt;/SPAN&gt;&amp;gt;         VisitInterfaceToken         { &lt;SPAN class=kwd&gt;get&lt;/SPAN&gt;; &lt;SPAN class=kwd&gt;set&lt;/SPAN&gt;; }
        &lt;SPAN class=clss&gt;Action&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=clss&gt;ClassToken&lt;/SPAN&gt;&amp;gt;             VisitClassToken             { &lt;SPAN class=kwd&gt;get&lt;/SPAN&gt;; &lt;SPAN class=kwd&gt;set&lt;/SPAN&gt;; }
        &lt;SPAN class=clss&gt;Action&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=clss&gt;IdentifierToken&lt;/SPAN&gt;&amp;gt;        VisitIdentifierToken        { &lt;SPAN class=kwd&gt;get&lt;/SPAN&gt;; &lt;SPAN class=kwd&gt;set&lt;/SPAN&gt;; }
        &lt;SPAN class=clss&gt;Action&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=clss&gt;ContextualKeywordToken&lt;/SPAN&gt;&amp;gt; VisitContextualKeywordToken { &lt;SPAN class=kwd&gt;get&lt;/SPAN&gt;; &lt;SPAN class=kwd&gt;set&lt;/SPAN&gt;; }
        &lt;SPAN class=clss&gt;Action&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=clss&gt;AccessibilityToken&lt;/SPAN&gt;&amp;gt;     VisitAccessibilityToken     { &lt;SPAN class=kwd&gt;get&lt;/SPAN&gt;; &lt;SPAN class=kwd&gt;set&lt;/SPAN&gt;; }
        &lt;SPAN class=clss&gt;Action&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=clss&gt;NoisyToken&lt;/SPAN&gt;&amp;gt;             VisitNoisyToken             { &lt;SPAN class=kwd&gt;get&lt;/SPAN&gt;; &lt;SPAN class=kwd&gt;set&lt;/SPAN&gt;; }
        &lt;SPAN class=clss&gt;Action&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=clss&gt;CommentToken&lt;/SPAN&gt;&amp;gt;           VisitCommentToken           { &lt;SPAN class=kwd&gt;get&lt;/SPAN&gt;; &lt;SPAN class=kwd&gt;set&lt;/SPAN&gt;; }
        &lt;SPAN class=clss&gt;Action&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=clss&gt;WhitespaceToken&lt;/SPAN&gt;&amp;gt;        VisitWhitespaceToken        { &lt;SPAN class=kwd&gt;get&lt;/SPAN&gt;; &lt;SPAN class=kwd&gt;set&lt;/SPAN&gt;; }
    }

    &lt;SPAN class=kwd&gt;public class&lt;/SPAN&gt; &lt;SPAN class=clss&gt;DefaultTokenVisitor&lt;/SPAN&gt; : &lt;SPAN class=clss&gt;ITokenVisitor&lt;/SPAN&gt;
    {
        &lt;SPAN class=kwd&gt;public virtual&lt;/SPAN&gt; &lt;SPAN class=clss&gt;Action&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=clss&gt;Token&lt;/SPAN&gt;&amp;gt;                  Default                     { &lt;SPAN class=kwd&gt;get&lt;/SPAN&gt; { ... } &lt;SPAN class=kwd&gt;set&lt;/SPAN&gt; { ... } }
        &lt;SPAN class=kwd&gt;public virtual&lt;/SPAN&gt; &lt;SPAN class=clss&gt;Action&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=clss&gt;Token&lt;/SPAN&gt;&amp;gt;                  VisitToken                  { &lt;SPAN class=kwd&gt;get&lt;/SPAN&gt; { ... } &lt;SPAN class=kwd&gt;set&lt;/SPAN&gt; { ... } }
        &lt;SPAN class=kwd&gt;public virtual&lt;/SPAN&gt; &lt;SPAN class=clss&gt;Action&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=clss&gt;KeywordToken&lt;/SPAN&gt;&amp;gt;           VisitKeywordToken           { &lt;SPAN class=kwd&gt;get&lt;/SPAN&gt; { ... } &lt;SPAN class=kwd&gt;set&lt;/SPAN&gt; { ... } }
        &lt;SPAN class=kwd&gt;public virtual&lt;/SPAN&gt; &lt;SPAN class=clss&gt;Action&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=clss&gt;InterfaceToken&lt;/SPAN&gt;&amp;gt;         VisitInterfaceToken         { &lt;SPAN class=kwd&gt;get&lt;/SPAN&gt; { ... } &lt;SPAN class=kwd&gt;set&lt;/SPAN&gt; { ... } }
        &lt;SPAN class=kwd&gt;public virtual&lt;/SPAN&gt; &lt;SPAN class=clss&gt;Action&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=clss&gt;ClassToken&lt;/SPAN&gt;&amp;gt;             VisitClassToken             { &lt;SPAN class=kwd&gt;get&lt;/SPAN&gt; { ... } &lt;SPAN class=kwd&gt;set&lt;/SPAN&gt; { ... } }
        &lt;SPAN class=kwd&gt;public virtual&lt;/SPAN&gt; &lt;SPAN class=clss&gt;Action&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=clss&gt;IdentifierToken&lt;/SPAN&gt;&amp;gt;        VisitIdentifierToken        { &lt;SPAN class=kwd&gt;get&lt;/SPAN&gt; { ... } &lt;SPAN class=kwd&gt;set&lt;/SPAN&gt; { ... } }
        &lt;SPAN class=kwd&gt;public virtual&lt;/SPAN&gt; &lt;SPAN class=clss&gt;Action&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=clss&gt;ContextualKeywordToken&lt;/SPAN&gt;&amp;gt; VisitContextualKeywordToken { &lt;SPAN class=kwd&gt;get&lt;/SPAN&gt; { ... } &lt;SPAN class=kwd&gt;set&lt;/SPAN&gt; { ... } }
        &lt;SPAN class=kwd&gt;public virtual&lt;/SPAN&gt; &lt;SPAN class=clss&gt;Action&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=clss&gt;AccessibilityToken&lt;/SPAN&gt;&amp;gt;     VisitAccessibilityToken     { &lt;SPAN class=kwd&gt;get&lt;/SPAN&gt; { ... } &lt;SPAN class=kwd&gt;set&lt;/SPAN&gt; { ... } }
        &lt;SPAN class=kwd&gt;public virtual&lt;/SPAN&gt; &lt;SPAN class=clss&gt;Action&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=clss&gt;NoisyToken&lt;/SPAN&gt;&amp;gt;             VisitNoisyToken             { &lt;SPAN class=kwd&gt;get&lt;/SPAN&gt; { ... } &lt;SPAN class=kwd&gt;set&lt;/SPAN&gt; { ... } }
        &lt;SPAN class=kwd&gt;public virtual&lt;/SPAN&gt; &lt;SPAN class=clss&gt;Action&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=clss&gt;CommentToken&lt;/SPAN&gt;&amp;gt;           VisitCommentToken           { &lt;SPAN class=kwd&gt;get&lt;/SPAN&gt; { ... } &lt;SPAN class=kwd&gt;set&lt;/SPAN&gt; { ... } }
        &lt;SPAN class=kwd&gt;public virtual&lt;/SPAN&gt; &lt;SPAN class=clss&gt;Action&lt;/SPAN&gt;&amp;lt;&lt;SPAN class=clss&gt;WhitespaceToken&lt;/SPAN&gt;&amp;gt;        VisitWhitespaceToken        { &lt;SPAN class=kwd&gt;get&lt;/SPAN&gt; { ... } &lt;SPAN class=kwd&gt;set&lt;/SPAN&gt; { ... } }
    }&lt;/PRE&gt;
&lt;P&gt;So far, this code just makes use of C# 2.0 features.&amp;nbsp; It might take a couple of minutes for your mind to wrap around it, but what we've ended up doing here is creating an type whose methods can be overridden trivially at runtime.&amp;nbsp; We do this by simulating methods with properties that return delegates.&amp;nbsp; For example, you can provide a method implementation by writing: ".VisitToken = ..." and that method can then be invoked just as you would expect: "VisitToken()".&amp;nbsp; While they are actually properties and delegates, they appear (for all intents and purposes) as methods that you can change at runtime.&amp;nbsp; In fact, from a syntactic perspective, the code is indistinguishable, and so we do not even need to change any or our visitor accept methods on our token classes.&lt;/P&gt;
&lt;P&gt;So what can we do with this?&amp;nbsp; Well, let's see what we can turn our parser code into thanks to the above classes:&lt;/P&gt;&lt;PRE class=coloredcode&gt;        &lt;SPAN class=kwd&gt;void&lt;/SPAN&gt; parseType()
        {
            parseModifiers();

            CurrentToken.AcceptVisitor(&lt;SPAN class=kwd&gt;new&lt;/SPAN&gt; &lt;SPAN class=clss&gt;DefaultTokenVisitor&lt;/SPAN&gt; {
                VisitClassToken     = token =&amp;gt; parseClass(),
                VisitInterfaceToken = token =&amp;gt; parseInterface(),
                &lt;SPAN class=cmt&gt;/* include other cases */&lt;/SPAN&gt;
                Default             = token =&amp;gt; &lt;SPAN class=cmt&gt;/*handle error*/&lt;/SPAN&gt;
            });

            &lt;SPAN class=cmt&gt;//Parse rest of type&lt;/SPAN&gt;
        }&lt;/PRE&gt;
&lt;P&gt;The code bahaves how it reads.&amp;nbsp; We create a simple visitor with most of the logic built in.&amp;nbsp; But at construction time we tell it how to behave when it sees a "class" or "interface" token.&amp;nbsp; And in those cases, we are able to specify the behavior through a lamba expression in a succint manner.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;The "Object Initializer" feature is what allows us to instantiate an object and assign into its fields (much like attribute constructors), in an expression form rather than a statement form.&amp;nbsp; The lambda expressions then allow us to easily create closures of code that we which to execute at a later point in time.&amp;nbsp; Both features are simply lightweight syntactic constructs on what's already available in C# 2.0, but as you can see from the following code, the difference it makes in code is enormous:&lt;/P&gt;&lt;PRE class=coloredcode&gt;        &lt;SPAN class=kwd&gt;void&lt;/SPAN&gt; parseType()
        {
            parseModifiers();

            ITokenVisitor visitor = &lt;SPAN class=kwd&gt;new&lt;/SPAN&gt; &lt;SPAN class=clss&gt;DefaultTokenVisitor&lt;/SPAN&gt;();
            visitor.VisitClassToken = &lt;SPAN class=kwd&gt;delegate&lt;/SPAN&gt; (&lt;SPAN class=clss&gt;ClassToken&lt;/SPAN&gt; token) {
                &lt;SPAN class=kwd&gt;this&lt;/SPAN&gt;.parseClass();
            };

            visitor.VisitInterfaceToken = &lt;SPAN class=kwd&gt;delegate&lt;/SPAN&gt; (&lt;SPAN class=clss&gt;InterfaceToken&lt;/SPAN&gt; token) {
                &lt;SPAN class=kwd&gt;this&lt;/SPAN&gt;.parseInterface();
            };

            &lt;SPAN class=cmt&gt;/* include other cases */&lt;/SPAN&gt;
            
            visitor.Default = &lt;SPAN class=kwd&gt;delegate&lt;/SPAN&gt; (&lt;SPAN class=clss&gt;Token&lt;/SPAN&gt; token) {
                &lt;SPAN class=cmt&gt;/*handle error*/&lt;/SPAN&gt;
            };

            CurrentToken.AcceptVisitor(visitor);

            &lt;SPAN class=cmt&gt;//Parse rest of type&lt;/SPAN&gt;
        }&lt;/PRE&gt;
&lt;P&gt;(In fact, it's probably worse than the initial example of visitors in C#).&amp;nbsp; Completely unintelligible IMO.&lt;/P&gt;
&lt;P&gt;While this code appears similar to Java's anonymous inner classes, they actually don't share almost nothing in common.&amp;nbsp; In Java you would be creating a instance of an unamed subclass of the DefaultTokenVisitor&amp;nbsp;type, whereas in C# you are just instantiating an instance of the actual DefaultTokenVisitor class.&amp;nbsp; In Java the method declarations we used were overrides of the methods defined in the DefaultTokenVisitor class, whereas in C# we're just assigning lambda expressions into our properties which we're using to simulate methods.&amp;nbsp; In Java, if we were to use the "this" keyword, we'd be referring to the instance of the anonymous inner class the code was executing in, whereas in C# the "this" still refers to the parser instance in scope.&amp;nbsp; By using these two constructs we end up with the ability to use visitors from C# easily with a syntax that is even less heavyweight than the corresponding java constructs.&amp;nbsp; There are many ways in which the code is simpler:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;The C# code doesn't need () on the instantiation of DefaultTokenVisitor.&amp;nbsp; Very minor. 
&lt;LI&gt;The C# code can eschew the "public void" on all it's visitation operations.&amp;nbsp; Nice, and cleans things up well. 
&lt;LI&gt;The C# code doesn't allows the type of the parameter to be optional.&amp;nbsp; If you want it, you can keep it.&amp;nbsp; However, you can leave it out and still have things statically checked at compile time.&amp;nbsp; It helps with code duplication to not have to say: VisitClassToken(ClassToken..., and instead say: VisitClassToken(token... 
&lt;LI&gt;The C# code doesn't need the {}'s if the code is a trivial expression or statement.&amp;nbsp; Very minor 
&lt;LI&gt;The C# code doesn't need to dismbiguate the instance of the parser and the instance of the inner class like java does.&amp;nbsp; So there's no need to write: Parser.this.parseInterface().&amp;nbsp; Instead you can just do the simple: this.parseInterface()&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;All in all, the C# version is about 2/3s the length and cuts out a lot of the cruft.&amp;nbsp; This allows you to intermingle your visitor logic with the rest of your code just as you'd like to be able to do.&lt;/P&gt;
&lt;P&gt;So while Linq is a focused effort from many different teams at Microsoft to provide powerful integrated query support, you can see that the individual features that have been introduced in C# can be used in a lot of powerful ways beyond just that.&amp;nbsp; Hopefully you'll have your own good ideas about how to use these new language features in other interesting ways.&amp;nbsp; If so, let me know so we can share it with the rest of the development community out there!&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=464668" width="1" height="1"&gt;</content><author><name>CyrusN</name><uri>http://blogs.msdn.com/CyrusN/ProfileUrlRedirect.ashx</uri></author></entry></feed>