Saturday, October 24, 2009

Now that Visual Studio 2010 Beta 2 is finally out the door, I’ve had a bit more time to spend coding on some of my personal projects. Yesterday, I happened upon a cool trick while using the new Generate from Usage feature. It was so helpful to me that I thought others might benefit, so I’m sharing it here.

The Anonymous Type Problem

When you need to project some data from a LINQ expression, anonymous types can be enormously convenient.

C# Query

Because anonymous types are… well… anonymous, they don’t have names that can be expressed in code. This is problematic if you want to expose an anonymous type as the return type of a function. I have run into this problem many times. When refactoring code, it’s easy to get into a situation like the one below.

Broken C# Function

So, how can you get around this problem? Well, there a few possibilities.

  1. You could replace ??? with object and use reflection to get at the properties. (Yuck!)
  2. You could make the function generic and add a parameter to “mumble” the anonymous type.1 (Awkward!)
  3. Assuming C# 4.0, you could replace ??? with dynamic.2 (No compiler errors!)

Because none of these solutions is particularly savory, most of us are forced to create a new named type to replace the anonymous type. Thankfully, there are some fantastic third-party refactoring tools out there that can automate this tedious process, but if you don’t use one of these tools you’re stuck writing the code by hand.

Actually, no, that’s not quite true.

Generate from Usage to The Rescue!

In Visual Studio 2010, the new Generate from Usage feature makes the task of coding up new classes a snap! Just type a new name for the anonymous type in the editor, making the code look like a type constructor followed by an object initializer. Then, press Ctrl+. to expand the smart tag that immediately appears and choose the first suggestion to generate a new class.

Generate Class

Next, expand each smart tag in the object initializer to generate each property.

Generate Property

When you’re finished, you should have a brand new class containing each property, declared as auto-implemented properties. Cool!

Generated Class

For Visual Basic coders, Generate from Usage is even easier. Let’s start with the same LINQ expression in VB. (Notice the lack of the “_” line continuation characters. Hooray for VB10 implicit line continuation!)

VB Query

Just like before, type the name of the new type that you wish to generate and press Ctrl+. to expand the smart tag. After choosing the first suggestion from the smart tag, you’re finished. The VB Generate Class feature will drill into the object initializer and generate all of the necessary properties at the same time that the class is generated.

VB Generate Class

Wrapping Up

Of course, this technique is not without flaws.

  • The resulting type is not immutable like the anonymous type that you’re replacing. To address this, you can easily modify the generated properties to be read-only.
  • The new type does not have the same structural equality semantics that anonymous types have. In practice, I’ve rarely run into an bug caused by anonymous type structural equality, but if this is a concern for you, use one of the excellent third-party tools that account for these differences.

 

1See Wes Dyer's excellent article for an example of this clever trick.
2Check out Bill Wagner's post for details.

posted on Saturday, October 24, 2009 10:01:40 AM (Pacific Standard Time, UTC-08:00)  #    Comments [5]

kick it on DotNetKicks.com