Upgrade your C# Skills part 2 – Compiler Inference, Object Initializers, and Anonymous Types
Well, that Title sure is a mouthful! “Compiler Inference”, “Object Initializers”, “Anonymous Types”: as fancy as these items sound, they are among some of the more mundane changes to C# 3.0. Don’t get me wrong: these changes lay the groundwork for all the really cool stuff going on in C#, especially LINQ. Truthfully, I should have covered these first, but I had actually been dreaming about Extension Methods, so I hope you’ll understand if I had to get that out of my system!
Compiler Inference
It probably isn’t fair for me to say this is “mundane”, but look at the two examples below:
// Old Way Person p = new Person(); string name = p.LastName + " " + p.FirstName; // New Way var p = new Person(); var name = p.LastName + " " + p.FirstName;
Doesn’t seem like much, does it? All we did was replace the explicit Type with a new keyword called var. When you see var, what you are seeing is an instruction to the compiler to figure out for itself what Type the resulting variable will be. This is NOT var like in PHP or other loosely typed languages. Once assigned by the compiler, all the Strongly Typed rules still apply. And var can only be used for local variables, so it won’t be replacing all type references any time soon.
In the example above, “var p = new Person();”, the compiler will infer from the return type that variable “p” should be of type “Person”. Granted, in this simple example it doesn’t really mean much. It does mean less typing, especially when looping through generic collections, but where it will really come into play is with Anonymous Types and LINQ. In fact, without Compiler Inference, Anonymous Types could not function, but more on that later in the article.
There is some debate going on as to when to use Compiler Inference. Some feel that using var whenever possible is just lazy and leads to less readable code. These people think that you should use it only when it is really needed. In other words, if I know p is going to be a Person, then why not say so explicitly? Personally, I don’t have an opinion. I’ll use it when it seems convenient and of course where it is required. It certainly makes looping through Collections nicer to write:
// assume people is a List<Person> foreach (var person in people) { Console.WriteLine("{0} {1} is {2} years old.", person.FirstName, person.LastName, person.Age); }
I have to think that if Person is later subclassed, fewer changes would be required to make this code continue to function. Is it lazy? Perhaps, but we all know that a good programmer is a lazy thief!
Object Initializers
Another cool feature are Object Initializers. Initializers allow you to set a series of Property variables when you create the object. How many times have you coded something like this:
Person p = new Person(); p.FirstName = "John"; p.LastName = "Smith"; p.Age = 32;
Now, you can shorten this considerably. Sort of like Array Initializers, which I’m sure we’ve all used, the syntax is a list of property=value pairs inside curly braces immediately following a constructor:
// You could, of course, use var here... Person p = new Person() {FirstName = "John", LastName = "Smith", Age = 32};
An interesting side note about IntelliSense: naturally, inside the initializer block, IntelliSense will show you the list of properties available for the Person object. As you use Properties in the Initializer block, you will notice that they disappear from IntelliSense. This is a quick way to make sure you set every property (if you need to), and should help prevent listing duplicate properties (which, incidentally, throws a compiler error).
Now, for some extra coolness, you can embed Object Initialization inside a Collection’s Object Initializing block, so that this:
List<person> people = new List<person>(); Person p = new Person(); p.FirstName = "John"; p.LastName = "Smith"; p.Age = 32; people.Add(p); Person p2 = new Person() p2.FirstName = "Jimmy"; p2.LastName = "Crackcorn"; p2.Age = 57; people.Add(p2); Person p3 = new Person(); p3.FirstName = "Mary"; p3.LastName = "Contrary"; p3.Age = 44; people.Add(p3);
Can now be done like this:
var people = new List<person>() {new Person() {FirstName = "John", LastName = "Smith", Age = 32}, new Person() {FirstName = "Jimmy", LastName = "Crackcorn", Age = 57}, new Person() {FirstName = "Mary", LastName = "Contrary", Age = 44}};
As you can see, this is very concise and readable code. Less Typing = More Cool!
Automatic Properties
Since we are talking about properties, at least in a round about way, I want to throw in a quick item you may not be aware of called Automatic Properties. We all know that we are supposed to be exposing access to our variables via properties, but a lot of the time all we want to do is to be able to read and write the variable data. As such, we end up with a lot of code that looks like this:
private string _firstName; public string FirstName { get { return _firstName; } set { _firstName = value; } }
Now, there is nothing wrong with this approach, but it feels a little verbose. To address this, you can now use an Automatic Property:
public string FirstName { get; set; }
The two main differences are that you do not define the variable, and you do not have to write the getter and setter logic. In fact, you’ll notice there aren’t even curly braces for get or set. The upside is that it is again less code for a common function. The downside is that you do not have an internal variable to access: you must use the Property name, even internally. Also, the Property must contain both the get and the set, so you cannot have a read-only Automatic Property. You also cannot add custom logic: get and set default behaviors are it.
The plus, though, is that if you start with an Automatic Property and need to add any of this functionality, you simply create the variable and update the Property as you would have before. There is nothing magic about Automatic Properties, this is just another example of the Compiler doing menial work for you. One last tidbit: in VS2008, if you use the “prop” code snippet, you will get the format of an Automatic Property by default. It really replaces the need for my Property Builder tool.
Anonymous Types
When I first learned about Anonymous Types, I didn’t think it would be all that big of a deal. The more I think about it though, the more I can see a use for it. And when I saw how they are used with LINQ, I was sold. Basically, you can define a Type without naming it or creating a separate class definition. Let’s revisit our Person and People class from before, only this time I am not going to define the Person Class:
var p1 = new {FirstName = "John", LastName = "Smith", Age = 32, FirstName="Harold"}; var p2 = new {FirstName = "Jimmy", LastName = "Crackcorn", Age = 57}; var p3 = new {FirstName = "Mary", LastName = "Contrary", Age = 44};
Here I have created three instances of my new Type, but I have not explicitly defined the type definition. Instead, the compiler has created a class for me and given it the Properties I listed (using our new friend, Compiler Inference). All of the properties are read-only, so once created, the values cannot be changed. Since the three objects above are all identical in their property names, all three objects are of the same (unknown) type. And IntelliSense still works as well: Typing “p1.” will reveal a list of the properties. I said earlier in the article that Anonymous Types could not function without Compiler Inference: hopefully it is obvious now what is happening above. “var” is the only option here, because the Type of the variable does not exist at design time. The Compiler must infer the Type to be of whatever class the Compiler creates, otherwise, you could not have Anonymous Types in a language like C# because of its strong typing.
Of course, there is a catch: as of yet, I have not figured out a way to use these in a list. You cannot use a Generic list, because there is no Type for strong typing. You can store them as Objects, but then you cannot cast them back out because there is no type. So what does this particular method buy you? In my opinion, not much. There could be an argument for using this method to replace the use of temporary Structs, a method I use frequently to store grouped information. But since I can’t store them in a list or pass these objects around, it would be a very limited approach.
There is, however, a necessary use for Anonymous Types: LINQ requires them to be able to create custom query results as a Collection. We’ll explore that more later this week, so be sure to check back.
Hi Joel,
Great posts you have.
Below is a way to add anonymous types to a list.
var list = (new[] { new { first = “f1”, last = “l1” } }).ToList();
list.Add(new { first = “f2”, last = “l2” });
list.Add(new { first = “f3”, last = “l3” });
list.Add(new { first = “f4”, last = “l4” });
foreach (var item in list)
{
Console.WriteLine(item.first, item.last);
}
Console.ReadKey();
I want to point out something as far as discussing properties. You can have something resembling an a private Automatic property. Just do the following:
public String Foo { get; private set; }
Whoops, I meant a read only Automatic property.