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