Tuesday, June 24, 2008

Fun with C# 3.0 (#1)

This is the first in a series of posts in which I explore new features of C# 3.0 available in Visual Studio 2008.

In this post, I introduce anonymous types and extension methods.

An anonymous type is an unnamed class that you can define simply by specifying the values of its properties. These properties are read-only and can be accessed through the usual property accessor syntax.

var employee = new { Name = "John Smith", Age = 44, Job = "Manager" };
Console.WriteLine(employee.Name);
Console.WriteLine(employee.Age);
Console.WriteLine(employee.Job);


ProcessData(employee);



The class is created at compile-time and the properties are available via IntelliSense. Note, however that if you want to pass the object to another method, it must be passed as an object, since the class is unnamed.



public void ProcessData(object data)


{


}




Once we have the object in our ProcessData method, we need to access the properties via Reflection. Here's where extension methods come in handy. An extension method is a method that is declared as a static method in static class and is in an accessible namespace. It will appear to add new methods to an object type. For example, I can add a method to the String class that removes spaces:



public static class Extend
{
public static string RemoveSpaces(this string s)
{
return s.Replace(" ", "");
}

}




The "this" parameter modifier indicates that it is an extension method and the type of the parameter (string) is the class that is modified. It is called like so:



Console.WriteLine(employee.Name.RemoveSpaces());

To ease the access to our anonymous type properties, we can create an extension method on the object class. The method will be called ValueOf() and will take the name of the property as a parameter:

public static class ReflectionExtensions
{
public static object ValueOf(this object obj, string name)
{
if (name == null) throw new ArgumentNullException("Property Name");

try
{
return obj.GetType().GetProperty(name).GetValue(obj, null);
}
catch (NullReferenceException)
{
return null;
}
}
}

Now in our ProcessData() method we can access the Property values:

public void ProcessData(object data)
{
Console.WriteLine("Employee Name = " + data.ValueOf("Name"));
Console.WriteLine("Employee Age = " + data.ValueOf("Age"));
Console.WriteLine("Employee Job = " + data.ValueOf("Job"));

}








No comments: