First of all “A method group is a set of overloaded methods resulting from a member lookup”. In my example I use the set of Console.WriteLine
methods with 19 overloads.
The definition of a method group in C# Language Specification also states that: “A method group is permitted in an invocation-expression (§7.6.5) , a delegate-creation-expression (§7.6.10.5) and as the left hand side of an is operator, and can be implicitly converted to a compatible delegate type (§6.6).”
I could think of one scenario where this functionality could be useful:
Action<string> print = (Action<string>)Console.WriteLine;
print("Hello!");
if (Console.WriteLine is Action<string>)
{
Console.WriteLine("We're compatible!");
}
First couple of lines show that we can ‘cast’ a method group Console.WriteLine
into a delegate. What actually happens is the “implicit conversion converted to a compatible delegate type”, which creates an instance of a delegate calling one of many overloaded Console.WriteLine
methods with compatible signature.
So according to specs we could use the “left side of is operator” feature mentioned above to test if the method group is compatible with a given delegate type (implicit conversion exists). This is what is checked inside the ‘if’ statement in the sample code.
Surprisingly, the code compiles, but gives a warning “The given expression is never of the provided ('System.Action') type”. So it looks like there will be no attempts to check the compatibility of the method group and the delegate type at runtime.
Hence, my questions:
The specification (4.0) explicitly calls out this specific case:
7.10.10 The
is
operator[...] The result of the operation
E is T
whereE
is an expression andT
is a type, is a boolean value [...]
So far, so good. The specification continues:
If
E
is a method group [...] the result is false.
Given this information, let's look at your questions.
Why are the methods groups allowed on the left-side of ‘is’ operator if the check cannot be performed at runtime?
The specification allows for this operation. See Lippert's answer on another question about how this came to be.
Why this construct gives a warning and not a compilation error?
The construct is syntactically valid, even though it always evaluates to false. The warning is just there to let you know that you may be doing something unintended.
Are there any practical scenarios of using method groups on the left side of ‘is’ operator?
Probably not. Maybe if you were passed an object
that may be a method group or may be something else this construct could be useful. (It's admittedly a contrived example, that represents some seriously questionable practices.)
Is this something reserved for future uses, i.e. it is envisaged that the code above will work someday?
No. Quoting again from Lippert "it would be a breaking change to make 'M is D' suddenly start returning true or being an error." [Emphasis in original]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With