C# 3.0 – The var “keyword” and anonymous classes

This is an explanation of why the var “keyword” is like it is, and how this effects anonymous classes. I should probably point out I’m nothing to do with the C# design team, so these are merely my own opinions.

 

The var is all about type inference, it’s important to remember this is still static typing. The var keyword informs the compiler that it should try and infer the type of variable; if it can not do this a compile error is generated. One very important aspect of the var keyword is that it can only be used with local variables, and even then are a few cases that are not allowed.

 

The nemerle project, which has a very similar type inference system, has a web site which has this interesting discussion on type inference. To paraphrase them more than I probable should, the reason they don’t offer type inference on anything other than local variables is that the only way the type of a parameter can be inferred is when the method is called, and a method may not actually be called. (Okay, they allow type inference on parameters of local functions, but these are local variables that just happen to functions)

 

However, for C# there is an even greater motivation than this for limiting the var keyword to local variables – backwards compatibility. “var” is not really a keyword in the strictest sense of the term, because it is forbidden to use keywords as class/struct/method/parameter/variable names and it is okay to use var in this way. This is problematic because could have a class called var, so this means we need some mechanism to know whether or not we are referring to the keyword var or the class var. In C# this is what is on the right had side of the statement, and if we where to allow the keyword var to be used as a method parameter then we could never know which one we meant, because there is no right hand side of the statement for a parameter. That’s an awful lot of talking so let’s look at a quick example, imagined the following:

 

public class var { … }

 

public class Program

{

         public void MyMethod (var thing1, // does this mean var keyword or var class??

                   string thing2,

                   int thing3)

         {

                   var myString = “Hello, world”;

                            // var here means string (System.String)

                   var myInt = 1;

                            // var here means int (System.Int32)

                   var myVar = new var();

                            // var here means the class var

                   var myVar2 = null;

// does this mean var keyword or var class??

                   var myVar3;

// does this mean var keyword or var class??

}

}

 

I think it’s fairly easy to see that there’s no way to infer what thing1, myVar2 or myVar3 mean and indeed the C# spec forbids all 3 usages of var. This means in my example it’s safe for the compile to determine that in the case of thing1, myVar2 or myVar3 var is referring to the class that I’ve defined.

 

Anyway, if even you don’t believe my explication of why var is like this, then please take one thing away form this explication: var can only be used for local variables. This is where the implications for anonymous types come in, because the only way anonymous types can be referred to is though the use of var this effectively means anonymous types cannot be passed in and out of a method.

 

Okay sure, you can pass them in or out as System.Object, but then what use is that? A downcast to actual type can’t be preformed so you can’t see its properties. I think this might be a little unclear, so let’s see another example:

 

object Foo()

{

         return new {ProductID = 1, Name = “premier item”};

}

 

static void Main()

{

         object bar = Foo();

}

 

Foo is a method that returns an anonymous type, thought the use of System.Object, a reference to that value is placed in bar, but we can’t refer to either of our types properties because our reference is of type object. We can’t cast our object to the correct type, because we have no way to say its name, its real CLR name is made up by some compiler naming convention. Change bar type from object to var would not help here either because its type would still be inferred as object, as that is the return type of Foo().

 

Okay, so you’re thinking these limitations may make anonymous types look a bit week and un-useful? Well I think anonymous types have a couple of specific uses that make them very interesting. I think these limitations are also great, because it means they won’t be used willy-nilly to make code unreadable as some people complain about. So the specific use which I think they should be used for is as a mechanism to provide shape to some data which will then be shown to the user. I think this simple example shows just how powerful this is, we are able to select some data then select out just the bids we want to show in just a handful of lines:

 

        private void Form1_Load(object sender, EventArgs e)

        {

            var methods = typeof(string).GetMethods();

            var methodDetails =

                from m in methods

                where ! m.IsStatic

                orderby m.Name

                select new {

                    Name = m.Name,

                    CallingConvention = m.CallingConvention,

                    Abstract = m.IsAbstract,

                    Virtual = m.IsVirtual,

                    Public = m.IsPublic

                } ;

 

            BindingSource bindingSource = new BindingSource();

            bindingSource.DataSource = methodDetails;

            dataGridView1.DataSource = bindingSource;

        }

 

The full source for this demo is available here.

Bookmark
dotnetkicks+, digg+, reddit+, del.icio.us+, dzone+, facebook+

Print | posted @ Monday, October 10, 2005 5:10 PM

Comments on this entry:

Gravatar # re: C# 3.0 – The var “keyword” and anonymous classes
by El Duderino at 3/19/2007 3:35 PM

Because of implicit typing you can cast an object to the appropriate anonymous type.
I found this on another site:

public static T Cast<T>(object o, T type) where T : class
{
return o as T;
}

var person = Cast(ojb, new { Name = "", Age = 0 });
Gravatar # re: C# 3.0 – The var “keyword” and anonymous classes
by Matt Quinn at 7/11/2008 5:01 PM

The above code is interesting conceptually but should never be used. I agree with the main article's view that var's are ideal for briefly extracting strongly typed subsets of data from other objects, LINQ queries and related tasks etc etc.

Persistant use, such as passing them around as arguments to parameters is bad practise IMHO.

To ellaborate, in the example above, the anonymous type appears to describe a person. So we'll name it Person. What if we decide to add a Gender property to Person? We can - but unfortunately the type definition for person effectively exists in every single call to Cast()! It's a scalability and extensiblity nightmare.
Gravatar # re: C# 3.0 – The var “keyword” and anonymous classes
by HaiL at 8/21/2008 11:17 AM

The example is good.
Let me see a little for the var keyword and Linq to SQL.
Gravatar # The reuse of keywords in the C++ standard | keyongtech
by Pingback/TrackBack at 1/18/2009 6:35 PM

The reuse of keywords in the C++ standard | keyongtech

Your comment:

(Note: all comments are moderated so it may take sometime to appear)

Title:
Name:
Email:
Website:
 
Italic Underline Blockquote Hyperlink
 
 
Please add 1 and 2 and type the answer here:
 

Links

 Subscribe in a reader
Twitter Follow me on Twitter
FaceBook View my Facebook
LinkedIn View my LinkedIn Profile Viadeo Viadeo Profile (Français)

Badges


Progressive .NET Tutorials 2009

Disclaimer

The views expressed on this weblog are mine and do not necessarily reflect the views of my employer.

All postings are provided "AS IS" with no warranties, and confer no rights.

www.flickr.com
This is a Flickr badge showing public photos and videos from Robert Pickering. Make your own badge here.