My friend Mark has a new
blog with some great .NET tips. He's been posting daily and it's been really good so far. Lots of good tips on C# language features for both .NET 3.0 and 2.0.
Mark and I presented some of these language features last week for our team at work and one of the things we tallked a bit about was
anonymous methods and some of the new delegate features. These features of C# are becoming increasingly important for developers to understand. I'd like to present this code to you today.
For the examples I implemented a class which (for kicks) does recursive addition - here is that class:
Using the "AdditionTheHardWay" class we can show a few different ways of using delegates with simple instance methods.
In the traditional way, available since .NET 1.0, you would first declare the delegate type with the type parameters you needed like so:
Once you had declared the delegate type you were free to use it with methods which had the same signature. Here is an example:
In the above test, we create an instance of the AdditionTheHardWay class and then assign the Add method to the AdditionDelegate. We can then invoke the delegate or function pointer at a later time or even add more methods to the delegate (the delegates in C# are multi-cast).
With .NET 2.0, Microsoft introduced a number of changes to the C# language which had a profound impact on how delegates could be used - the first of these is generics. Generics allow us to use type arguments for the delegate types. Here is a delegate declaration using generics:
With this new generic delegate declaration we are free to assign methods which do not accept integer arguments. In this case any method which takes two parameters and returns some value will match our generic delegate.
The second major feature introduced with .NET 2.0 was delegate inference. With delegate inference we no longer need to specify the type of our delegate when assigning it. Here is another example:
In this test we use the GenericDelegate type for our delegate with integer type arguments but when we assign the Add method we don't need to specify the delegate type again. The complier is able to infer the type which allows us to shorten and simplify the syntax a bit.
The final feature introduced with .NET 2.0 which is relevant here is anonymous methods. With an anonymous method you can create your delegate or function pointer inline. Here is an example:
There are a few things going on in the example above which may not be obvious. First, the anonymous method syntax requires the use of the delegate keyword. After the delegate keyword, specify any parameters that the anonymous method will take and then, within the curly braces, you write the method itself. Pretty straight forward, right?
In this case we are assigning the anonymous method to a delegate of type Func<int, int>. This is a built-in generic delegate type which shipped with .NET 3.0 along with a number of other built-in generic delegate types (a subject for another post). For now, know that this is the same as any method which will take an argument and return a value.
Finally, of note in the above example, is that in creating an anonymous method which takes a parameter we are actually creating a
closure - which is simply a variable bound to a method. This is a very powerful technique which is made possible through the use of anonymous methods.
posted @ Saturday, April 05, 2008 8:21 PM