If you have:
F(G<A,B>(4));
does this mean that the user wants to call a method F with 2 parameters that result from comparing G and A, and B and the constant 4?
Or does it mean call F with the result of calling generic method G using type parameters A and B and an argument of 4?
So I tried it out just to be sure. It turns out this works just fine:
void F(int x) { }
int G<T, U>(int x) { return x; }
class A { }
class B { }
void Main()
{
F(G<A,B>(4));
}
But this produces a number of compile errors:
void F(bool x, bool y) { }
void Main()
{
int G = 0, A = 1, B = 2;
F(G<A,B>(4));
}
The type or namespace name 'A' could not be found (press F4 to add a using directive or assembly reference)
The type or namespace name 'B' could not be found (are you missing a using directive or an assembly reference?)
The variable 'G' is not a generic method. If you intended an expression list, use parentheses around the < expression.
So the answer is that the expression F(G<A,B>(4))
is interpreted as a generic function call. There are any number of ways to force the compiler to treat this as a single function call of two parameters: F(G<A,B>4)
, F((G)<A,B>(4))
, or F(G>A,B>(4))
, just to name a few.
You should read 7.6.4.2 of the C# spec, which deals with grammar ambiguities and discusses this example almost verbatim. To quote:
If a sequence of tokens can be parsed (in context) as a simple-name (§7.6.2), member-access (§7.6.4), or pointer-member-access (§18.5.2) ending with a type-argument-list (§4.4.1), the token immediately following the closing
>
token is examined. If it is one of( ) ] } : ; , . ? == != | ^
then the type-argument-list is retained as part of the simple-name, member-access or pointer-member-access and any other possible parse of the sequence of tokens is discarded.
Here, G
is a simple-name and the question is whether <A,B>
is to be interpreted as a type-argument-list as part of this simple name.
There is a (
after the >
, so the fragment G<A,B>
is the simple-name of a method. The method is a generic method with type arguments A
and B
and an argument of 4. F
is therefore a method with a single parameter.
One interesting thing to note is that this is a case where the compiler does not consider any alternatives if parsing fails. As you can see from pswg's answer, even if the only valid interpretation is one where F
is a method that takes two parameters, it is not considered.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.