Secondo voi, se questo snippet compila:
class Test
{
static void Foo(bool b1, bool b2)
{
System.Console.WriteLine("{0}, {1}", b1, b2);
}
static void Main()
{
bool b1 = expr1;
bool b2 = expr2;
Foo(b1, b2);
}
}
e lasciando identiche le espressioni expr1 e expr2, dovrebbe per forza compilare senza errori anche quest'altro snippet?:
class Test
{
static void Foo(bool b1, bool b2)
{
System.Console.WriteLine("{0}, {1}", b1, b2);
}
static void Main()
{
Foo(expr1, expr2);
}
}
Non sempre! Ed eccone un esempio, suggerito dalle specifiche (ECMA-334, 3rd Ed., 9.2.3 "Grammar ambiguities" - dove troverete anche altre situazioni!):
// compila senza errori e stampa True, False
class Test
{
static void Foo(bool b1, bool b2)
{
System.Console.WriteLine("{0}, {1}", b1, b2);
}
static void Main()
{
int a = 1;
int b = 2;
int c = 3;
bool b1 = a<b;
bool b2 = c>(4+5);
Foo(b1, b2);
}
}
// errori di compilazione: 2 errori CS0246 e 1 errore CS0471
class Test
{
static void Foo(bool b1, bool b2)
{
System.Console.WriteLine("{0}, {1}", b1, b2);
}
static void Main()
{
int a = 1;
int b = 2;
int c = 3;
Foo(a<b, c>(4+5));
}
}
L'ambiguità è risolta in modo un po' radicale (molto probabilmente per motivi di performance del compilatore):
"If a sequence of tokens can be parsed (in context) as a simple-name, member-access, or pointer-member-access ending with a type-argument-list, 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. Otherwise, the type-argument-list is not considered part of the simple-name, member-access or pointer-member-access, even if there is no other possible parse of the sequence of tokens."