New Features of C# 4.0
- Optional Parameters and Named arguments
- Dynamic typing
- Com interop
- Convariance and Contravariance
Optional Parameters and Named arguments
It 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 value
Now 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
Named Parameters
Named parameters provide the solution:
ArrayList myArrayList = new ArrayList();
Process( "foo", true ); // valid, moreData omitted
Process( "foo", true, myArrayList ); // valid
Process( "foo", moreData: myArrayList); // valid, ignoreWS omitted
Process( "foo", moreData: myArrayList, ignoreWS: false ); // valid, but silly
As long as a parameter has a default value, it can be omitted, and you can just supply the parameters you want via their name. Note in the second line above, the '
true
' value for ignoreWS
did not have to be named since it is the next logical parameter.Dynamic Support
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 declares
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 callcust.MissingMethod()
will compile and not fail until runtime. The result of this operation is 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";
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 becauseMath.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