Monday, May 9, 2011

.NET 4.0 New Feature

Feature Categories
Microsoft breaks the new features into the following four categories so I will maintain the pattern:
•Named and Optional Parameters
•Dynamic Support

Optional Parameters
Support for optional parameters allows you to give a method parameter a default value so that you do not have to specify it every time you call the method. This comes in handy when you have overloaded methods that are chained together.

The Old Way

public void Process( string data )
{
Process( data, false );
}

public void Process( string data, bool ignoreWS )
{
Process( data, ignoreWS, null );
}

public void Process( string data, bool ignoreWS, ArrayList moreData )
{
// Actual work done here
}The reason for overloading Process in this way is to avoid always having to include "false, null" in the third method call. Suppose 99% of the time there will not be 'moreData' provided. It seems ridiculous to type and pass null so many times.

// These 3 calls are equivalent
Process( "foo", false, null );
Process( "foo", false );
Process( "foo" );

The New Way
public void Process( string data, bool ignoreWS = false, ArrayList moreData = null )
{
// Actual work done here
}
// Note: data must always be provided because it does not have a default valueNow we have one method instead of three, but the three ways we called Process above are still valid and still equivalent.

ArrayList myArrayList = new ArrayList();
Process( "foo" ); // valid
Process( "foo", true ); // valid
Process( "foo", false, myArrayList ); // valid
Process( "foo", myArrayList ); // Invalid! See next section



Dynamic
The dynamic keyword is new to C# 4.0, and is used to tell the compiler that a variable's type can change or that it is not known until runtime. Think of it as being able to interact with an Object without having to cast it.

dynamic cust = GetCustomer();
cust.FirstName = "foo"; // works as expected
cust.Process(); // works as expected
cust.MissingMethod(); // No method found!Notice we did not need to cast nor declare cust as type Customer. Because we declared it dynamic, the runtime takes over and then searches and sets the FirstName property for us. Now, of course, when you are using a dynamic variable, you are giving up compiler type checking. This means the call cust.MissingMethod() will compile and not fail until runtime. The result of this operation is a RuntimeBinderException because MissingMethod is not defined on the Customer class.

The example above shows how dynamic works when calling methods and properties. Another powerful (and potentially dangerous) feature is being able to reuse variables for different types of data. I'm sure the Python, Ruby, and Perl programmers out there can think of a million ways to take advantage of this, but I've been using C# so long that it just feels "wrong" to me.

dynamic foo = 123;
foo = "bar";OK, so you most likely will not be writing code like the above very often. There may be times, however, when variable reuse can come in handy or clean up a dirty piece of legacy code. One simple case I run into often is constantly having to cast between decimal and double.

decimal foo = GetDecimalValue();
foo = foo / 2.5; // Does not compile
foo = Math.Sqrt(foo); // Does not compile
string bar = foo.ToString("c");The second line does not compile because 2.5 is typed as a double and line 3 does not compile because Math.Sqrt expects a double. Obviously, all you have to do is cast and/or change your variable type, but there may be situations where dynamic makes sense to use.

dynamic foo = GetDecimalValue(); // still returns a decimal
foo = foo / 2.5; // The runtime takes care of this for us
foo = Math.Sqrt(foo); // Again, the DLR works its magic
string bar = foo.ToString("c");

No comments:

Post a Comment