Page 1 of 2 Anonymous methods aren't particularly new, but they have hidden depths and lead on to lambda expressions.
Anonymous methods were introduced back in .NET 2.0 and while they sound like something designed to implement “dirty” shortcuts they are a welcome addition to C#.
The big problem with anonymous methods is figuring out what the problem is that they are designed to solve.
So let’s take a look at what they are for.
On one level anonymous methods are just about making delegates easier to create.
Delegates
A delegate is just an object that “wraps” a function.
It is what you need when functions are not in themselves first class objects. That is you can't pass a function as argument to another function so you have to wrap it in an object so that you can pass the object and a delegate is just an object designed for wrapping a function.
Before you can use a delegate to wrap a function you have to create a delegate type that has the signature of the function you want to wrap. That is every delegate wrapper carries information about the function it wraps in its type - this is used to detect simple errors.
Then you instantiate the type, wrap the function and use it.
So the steps to create and use a delegate are
- Create the delegate type which specifies the signature and return type.
- Write the method that you want the delegate to "wrap".
- Instantiate the delegate type created in step 1 and use it to wrap the method.
What all this means is that you have to invent multiple names for what in most cases is a single idea -
- the delegate type - MyDelegateType
- the method to be wrapped - MyMethod
and
- the instance doing the wrapping - MyDelegate
For example, if you want to wrap a “Hello World” function you first create a suitable delegate type:
delegate void MyHelloDelegateType();
then you have to create the function within some class or other:
void Hello(){ MessageBox.Show("Hello From a Delegate"); }
and finally create an instance of the delegate type specifying the function that it is to wrap:
MyHelloDelegateType MyHelloDelegate1 = new MyHelloDelegateType (Hello);
or equivalently:
MyHelloDelegateType MyHelloDelegate1 = Hello;
Calling the function via the delegate is just a matter of using its name:
MyHelloDelegate1();
You can see that we have had to invent three names:
- MyHelloDelegateType - the delegate type
- Hello - the method name
- MyHelloDelegate - the wrapper instance
This is fine if you are going to create multiple instances of the type and wrap multiple functions but in most cases the type, the delegate and the method are more or less a single entity.
That is you create a delegate because you want to use a method as if it was an object and often this is a one-off requirement.
Anonymous methods
The idea of an anonymous method allows you to fuse the identity of the delegate with the function it wraps.
For example, we can create an instance of MyHelloDelegateType:
MyHelloDelegateType MyHelloDelegate1=delegate(){ MessageBox.Show("Hello From a Delegate"); };
MyHelloDelegate1();
One identifier fewer might not seem much of a victory but now we can recast the code to express the fact that the delegate type is really about the signature and the delegate instance is about what actually happens by renaming the delegate “Hello” i.e. the name that we probably would have assigned the method:
MyHelloDelegateType1 Hello = delegate(){ MessageBox.Show("Hello From a Delegate"); };
Hello();
You can specify parameters in the function definition by treating the keyword “delegate” as if it was the function’s name. For example:
MyHelloDelegateType2 Hello2 = delegate(string Msg){ MessageBox.Show(Msg); };
However for this to work we need to define another delegate type that matches the new signature:
delegate void MyHelloDelegateType2(
string MyString);
Notice that the identifier used as the parameter in the type definition doesn’t carry any meaning – it’s just there for the syntax.
Perhaps the C style signature specification:
delegate void MyHelloDelegateType2(string);
would be better but notice, this doesn’t work in C# because its C syntax and this is C#.
With the type defined we can now call the delegate in the usual way:
Hello2("Hello delegate 2");
The situation is a little more complicated than this simple example suggests.
In fact the anonymous method doesn’t have to match the signature of the delegate type exactly.
As long as the delegate type has no out parameters then the anonymous method can be defined with no parameters.
For example the following is perfectly legal even though the delegate type specifies a single string parameter:
MyHelloDelegateType2 Hello3 = delegate { MessageBox.Show("Default message!"); };
However you still have to call the delegate with the correct signature:
Hello3("dummy");
The parameter supplied is simply thrown away and you can see why this approach doesn’t work with out parameters. If there is an out parameter defined, where would the return value come from?
<ASIN:1449320104>
<ASIN:161729134X>
<ASIN:1430242337>
<ASIN:0735668019>
<ASIN:1449343503>
|