When branching to select a function, it might make sense to use the ternary operator to select a function, but this is impossible. Why?
public class Demo {
protected bool branch;
protected void demo1 () {}
protected void demo2 () {}
public Action DoesntWork() {
return branch ? demo1 : demo2;
}
}
The compiler produces the following error:
Cannot implicitly convert type `method group' to `System.Action'
You have to explicitly create the delegate of the appropriate type. Normally, you can just use
demo1
to refer to aSystem.Action
, but that is only because the compiler can infer the type based on the usage and creates the delegate for you. In this case, the compiler doesn't know that your method should be converted toSystem.Action
when used within the ternary operator.If you supply this yourself for even one of the arguments, it will work:
Since this returns
new Action
explicitly for one argument, the compiler can infer that the other should be converted appropriate to aSystem.Action
, and it will compile successfully.The problem is that
demo1
is not a simple expression, it is a method. And methods can be overriden, so it is not actually one method, it is a method group. Consider the following example:Now,
demo1
is overloaded, so which one of the two versions should be used? The answer is that the overloaded function is selected by using the context in which the function is used.In the
return demo1
it is obvious, it expects anAction
.But in the
return branch? demo1 : demo2;
the context is not so easy. The ternary operator first tries to match the type ofdemo1
with that ofdemo2
, but that is another method group so there is no help there. The compiler does not look beyond and fails.The solution is to make clear the type expected from the method group: