Des idées profondes appréciées.
Je ferai de mon mieux.
Comme d'autres réponses l'ont noté, ce qui se passe ici, c'est que le compilateur détecte qu'une expression est utilisée comme une déclaration. Dans de nombreux langages -- C, JavaScript et bien d'autres -- il est tout à fait légal d'utiliser une expression comme une déclaration. 2 + 2;
est légal dans ces langages, même si c'est une déclaration qui n'a aucun effet. Certaines expressions sont utiles uniquement pour leurs valeurs, certaines expressions sont utiles uniquement pour leurs effets secondaires (comme un appel à une méthode renvoyant void) et certaines expressions, malheureusement, sont utiles pour les deux. (Comme l'incrémentation.)
Le point important est que les déclarations qui ne consistent qu'en des expressions sont presque certainement des erreurs à moins que ces expressions soient généralement considérées comme plus utiles pour leurs effets secondaires que pour leurs valeurs. Les concepteurs de C# ont souhaité trouver un juste milieu en autorisant les expressions qui étaient généralement considérées comme ayant des effets secondaires, tout en interdisant celles qui sont également généralement considérées comme utiles pour leurs valeurs. Le jeu d'expressions qu'ils ont identifié dans C# 1.0 était les incréments, les décréments, les appels de méthode, les affectations et, de manière quelque peu controversée, les invocations de constructeur.
À PART : On pense normalement qu'une construction d'objet est utilisée pour la valeur qu'elle produit, et non pour l'effet secondaire de la construction ; à mon avis, autoriser new Foo();
est un peu une mauvaise idée. En particulier, j'ai vu ce pattern dans du code du monde réel qui a provoqué un défaut de sécurité :
catch(FooException ex) { new BarException(ex); }
Il peut être étonnamment difficile de repérer ce défaut si le code est compliqué.
Le compilateur travaille donc pour détecter toutes les déclarations qui consistent en des expressions qui ne sont pas dans cette liste. En particulier, les expressions entre parenthèses sont identifiées comme telles -- des expressions entre parenthèses. Elles ne figurent pas sur la liste des "autorisées en tant qu'expressions de déclaration", donc elles sont interdites.
Tout cela sert à un principe de conception du langage C#. Si vous avez tapé (x++);
vous faisiez probablement quelque chose de mal. C'est probablement une faute de frappe pour M(x++);
ou quelque chose du genre. Rappelez-vous, l'attitude de l'équipe du compilateur C# n'est pas "pouvons-nous trouver un moyen de faire fonctionner cela ?". L'attitude de l'équipe du compilateur C# est "si le code plausible ressemble à une erreur probable, informons le développeur". Les développeurs C# aiment cette attitude.
Cela dit, il y a en fait quelques cas curieux où la spécification C# implique ou affirme explicitement que les parenthèses sont interdites mais le compilateur C# les autorise quand même. Dans presque tous ces cas, la légère divergence entre le comportement spécifié et le comportement autorisé est totalement inoffensive, donc les rédacteurs du compilateur n'ont jamais corrigé ces petits bugs. Vous pouvez en lire davantage ici :
_
Y a-t-il une différence entre return myVar vs. return (myVar) ?
_