Why does "Func<bool> test = value ? F: F" not compile?
I have seen similar questions to this, but they involve different types so I think this is a new question.
Consider the following code:
public void Test(bool value)
{
// The following line provokes a compiler error:
// "Type of conditional expression cannot be determined because there is
// no implicit conversion between 'method group' and 'method group".
Func<bool> test = value ? F : F;
}
public bool F()
{
return false;
}
Now, according to the C# 3.0 Standard,
The second and third operands of the ?: operator cont开发者_JAVA技巧rol the type of the conditional expression. Let X and Y be the types of the second and third operands. Then,
If X and Y are the same type, then this is the type of the conditional Otherwise, if an implicit conversion (§6.1) exists from X to Y, but not from Y to X, then Y is the type of the conditional expression. Otherwise, if an implicit conversion (§6.1) exists from Y to X, but not from X to Y, then X is the type of the conditional expression. Otherwise, no expression type can be determined, and a compile-time error occurs.
It seems to me that in my sample code, X and Y must be of the same type, since they are the selfsame entity, Func. So why does it not compile?
The question was changed significantly, so my original answer is a bit off by now.
However, the problem is essentially the same. I.e. there could be any number of matching delegate declarations for F
and since there is no implicit conversion between two identical delegate declarations the type of F
cannot be converted to Func<bool>
.
Likewise, if you declare
private delegate void X();
private delegate void Y();
private static void Foo() {}
You cannot do
X x = Foo;
Y y = x;
Original answer:
It doesn't work because method groups cannot be assigned to an implicitly typed variable.
var test = Func;
doesn't work either.
The reason being that there could be any number of delegate types for Func
. E.g. Func
matches both of these declarations (in addition to Action
)
private delegate void X();
private delegate void Y();
To use implicitly typed variables with method groups, you need to remove the ambiguity by casting.
See archil's answer for a concrete example of one way to fix this. That is, he shows what the corrected code might look like [assuming the delegate you desire to match is Action
].
var test = value ? (Action)Func: (Action)Func;
Actually, type
of method is expressed by delegate it matches. System.Action
that i used to cast methods to, is the delegate with signature returning void and taking no parameters - it matches your Func()
method. And now your test
will know that it is type of System.Action. Delegates are something like interfaces for methods. Take a look at http://msdn.microsoft.com/en-us/library/ms173171(v=vs.80).aspx
精彩评论