Sunday, October 28, 2007

.NET 3.5: The Good Stuff

With my last two postings "Partial Methods. What The?" and "C# 3.0 Extension Methods? A Good Idea?" taking shots at new features in .NET 3.5, I wanted to make a new post where I look at some of the new features I'm actually excited about. Even though this blog is titled "Chapman's Constant Complaining", I'm not negative about everything! There is a lot of good on the horizon.

1. Anonymous Types

Anonymous types are tool in .NET 3.5 that allows you to specify types based on the properties contained in the type, rather than the class declaration. The type has no name, meaning that you will not be able to construct a new instance of this type by using the new className() mechanism.

Basically, anonymous types free the developer from having to define a new class for every one off purpose in the application. I'm an NHibernate addict. I think it's absolute fabulous tool, and if you're reading this and you've never tried it, go download it right now. You can find it at Anyway, with NHibernate I find myself creating classes all the time which contain just the data I want returned from a query. You then create a constructor which takes just the fields you want and then reference this type in your HQL query. This is very helpful when trying to tune an HQL query for a complex search page where you need to collect display data from many objects, or even aggregates of child data.

In theory anonymous types will free developers from this time consuming task. NHibernate, much like LINQ, would be able to construct a new anonymous type for us containing just the properties we asked the HQL to return us. Note that this is actually the main use of anonymous types in .NET 3.5, support for arbitrary data being returned from LINQ expressions.

Anonymous types go beyond just queries though. How many times have you needed a simple two or three property class to perform calculations within a method? I've created one off "info" classes in the past. I don't know why I call them info, I just do. We now have the ability to define that "info" class as an anonymous type and no longer worry about the actual class declaration.

2. LINQ (Language Integrated Query)

This is the big daddy of .NET 3.5. Who hasn't heard of LINQ? The way it has been talked about it sounds like it will solve every problem ever created by a developer. I actually think LINQ is way over hyped. over hyped or not, it's still a very cool new feature which will change how we develop applications with .NET going forward.

First, I want to cover why I think LINQ is over hyped. LINQ is being talked about like there has never been anything similar in the past. Most examples which are provided are used to query a database using LINQ to SQL which is really just a very simplified OR/M tool. What some people don't realize is that tools like NHibernate, LLBLGen Pro, Entity Spaces and others have been around for a long time, offering better OR/M tools and very sophisticated query mechanisms for some time.

Now, LINQ still deserves it's credit here because it actually takes what we've learned from our OR/M tools a bit further. I'm most exited about having strong typing on my queries written in C#. I hate that the only tools I have available to me are based on strings. If an object's property is renamed it is often very difficult to spot any potential queries which were not updated until runtime. Having this check performed at compile time is a huge advantage.

Secondly I think it helps people look at their C# objects in a different manner. When trying to explain OR/M tools to developers who haven't previously used an OR/M I try to explain that the OR/M is really a synchronization tool, not a database persistence tool. Think of the database as just your extended memory, perhaps a second level memory store. As far as you are concerned there is no difference between objects in memory and objects in a database. LINQ helps to re-enforce this thinking in that you can write the same queries against your objects in memory as you do your objects in the database. I think this may cause some issues for some people at first, but eventually will be very beneficial.

3. Object Initializers

This is sort of a minor one. Object Initializers seem like they are purely syntactic sugar which can be skipped, but they allow us to offer new features like the above mentioned anonymous types and LINQ. Object initializers also allow us to offer mechanisms to define our objects without having to worry about which constructors the class's author defined for us. I think overall it makes the code a bit cleaner and easier to read.

4. Type Inference (The C# var keyword)

This could be argued as a minor point as well, except for the necessity of the feature for the above mentioned anonymous types and LINQ. I think it is convenient to be able to declare types with a var keyword when declaring a variable with an assignment.

That being said, it is a feature I don't see myself using a whole lot. I would prefer to type the entire type when it is known. This makes it a bit easier to read the code in my opinion. If you are using an IDE like Visual Studio 2008 it should not make much of a difference, but is it really that hard to write int i = 1 instead of var i = 1? I know we're really concerned about the long generic types, but a little extra typing never hurt anyone.

So while I think this is a very useful feature, I'm a little concerned that it may be taken to the extreme in some code where every variable declaration is defined as var. Plus people already make the mistake of constructing new types only to throw them away on the next line. I hope this doesn't make that problem worse. Who hasn't seen the following code?

ArrayList list = new ArrayList();
list = RunQuery();

5. Lots of Other Stuff

There are actually many other cool features built in to .NET 3.5 for us, like built in APIs for RSS 2.0 and ATOM as well as an improved garbage collector. Overall I'm excited about .NET 3.5. Now if only we could do something about those extension methods and partial methods!

--John Chapman


David said...

Hey man, good stuff here. I'd just like to Add that it's not only the ORM stuff that makes LINQ great. It's also the ability for me to query...well anything that stores data. Plus all the Addons like the anonymous types and Extension methods that are pulled into C# to support LINQ.

Keep up the good work man :)

John Chapman said...

Dave, you are right, I probably should have mentioned that a little better than I did. The post already seemed long enough!

I tried to hit on this point when I was stating that it changes our perspectives on the separation of objects and databases. Since LINQ is a tool that queries on your database or your objects in memory (my specific example) or anything else, it helps to promote a change in mindset.

At least that was meant to be my take on it.

Thanks for the comments

Adam Tybor said...

If your an NHibernate addict, no doubt you have seen Ayende's NHibernate Query Generator in his Rhino Tools project. This is a strongly typed linq like query interface for the 2.0 platform. There is also an experimental branch that has linq for NHibernate.

John Chapman said...


Thanks for the comments. I don't know if you realized this from the post but I have 0 interest in using LINQ to SQL. The goal is to wait for LINQ to NHibernate to be solid and then use that. The advantage is the strongly typed queries. Ayende's query generator does work for this purpose, but I feel that a lot of our current work is too complex to work through that tool.

Blogger Syntax Highliter