I was reading Jon Skeet’s answer here
and one of his samples was :
static void Main()
{
int x = 0;
Foo( delegate { return x; } );
}
static void Foo(Func<int, int> action)
{
Console.WriteLine("I suspect the anonymous method...");
}
But how Foo(Func<int, int>) can deal with delegate { return x; } which is Func<int> ?
As a matter of fact also Func< int,int,int,int,...> can deal with delegate { return x; } …
question 1
Any explanation for this behavior please ?
question 2
I have this code :
class MyClass
{
public delegate void MyEventHandler(object sender);
public event MyEventHandler MyEvent;
}
and I wanted to use generic handlers so :
class MyClass
{
public Action<object> MyEventHandler;
public event MyEventHandler MyEvent;
}
but I get this error :
‘UserQuery.MyClass.MyEventHandler(object)’ is a ‘method’ but is used like a ‘type’
Why isn’t it recognizing it ?
The answer to your first question is that the arguments to the delegate are inferred by the compiler. An anonymous method is compiled that takes an
intas an argument, and does nothing at all with it. The code could have been written like this:By omitting the parameter list, you are telling the compiler to emit a method that has the same argument types as the delegate type in the current context. The compiler knows that a
Func<int, int>is expected, so it is able to make the anonymous method’s argument types match.In other words,
delegate { ... }tells the compiler “create an anonymous method, but I don’t care what the arguments are because I’m not going to use them, so emit whatever arguments will allow this delegate to be acceptable in this context.” (This is different fromdelegate () { ... }which means “create an anonymous method that takes zero arguments.” Note the parentheses. If you add these parentheses to your example code, it will indeed fail to compile.)In the second case, you are using a field name where a type name is expected. Defining a field does not create a type with the field’s name. Your first example is correct; in that case,
MyEventHandleris a type and not a field. (Even if that did work, using generics would not really be helpful, since the final delegate signature is already determined at compile time. You would get no net advantage from using generics.)