A lambda like (int a) => a
will fit any delegate that takes an int
and returns an int
. Func<int,int>
is just a single example, and you could easily declare one yourself with delegate int Foo(int x);
. In fact this lambda expression will even fit a delegate that takes an int
and returns a double
, because the result of the lambda (a
) is implicitly convertible to double
.
In order for a lambda to be assignable to all the delegate types that it would fit, the lambda itself doesn't inherently have a type. Instead it takes on the type of the delegate you're using it as, as long as that's possible. ((int a) => a
can't be assigned to Func<byte, byte>
of course.)
While both Func<int, int>
and the Foo
delegate I defined can of course be converted to Delegate
, a lambda can not be directly converted to Delegate
because it is unclear what its actual signature would then be. After Delegate d = (int a) => a
, would d
be Foo
, or Func<int, int>
, or even Func<int, double>
? All are valid possibilities, and the compiler has no idea what you intended. It could make a best guess, but C# is not the kind of language that does that kind of guesswork. This is also why you can't do something like var = (int a) => a
.
I do think the error message that the compiler gives for Delegate d = (int a) => a;
is very unclear:
Cannot convert lambda expression to type 'System.Delegate' because it is not a delegate type
Intuitively you would think Delegate
is a delegate type, but that's not how things work. :)