Pourquoi la déclaration (j++); interdit?
Le code suivant est incorrect (voir sur ideone):
public class Test
{
public static void Main()
{
int j = 5;
(j++); //if we remove the "(" and ")" then this compiles fine.
}
}
erreur CS0201: Seule la cession, l'appel, incrémentation, décrémentation, attendent, et
de nouvelles expressions d'objet peut être utilisé comme une déclaration
- Pourquoi le code de la compilation quand on enlève les parenthèses?
- Pourquoi ne pas compiler avec les parenthèses?
- Pourquoi C# conçu de cette façon?
- beaucoup de personnes sont impliquées avec le langage C# design sont TELLEMENT, donc c'est pourquoi j'ai demandé. Rien de mal à cela?
- Le compilateur attend une déclaration ici, mais ces parenthèses indiquent une valeur.
- Je ne peux pas imaginer un plus sur le sujet de la question de "pourquoi un langage de programmation particulier gérer ce comportement spécifique de cette façon?"
- se sent comme il tomberait sous constructif subjective de la question, stackoverflow.com/help/dont-ask
- Compte tenu de la réponse a déjà attiré des réponses sur 4 qui ne suivent pas ces points, de toute évidence, elle ne l'est pas. Il n'est également pas spécifiquement un programme pratique de problème.
- à partir de la question, quelqu'un pourrait raisonnablement pontificat sur le but derrière pourquoi il n'est pas valide ("intuitions Profondes apprécié"). Il y a quelques très bien, C# experts qui pourraient comprendre les conséquences de la décision en dépit de ne pas être les créateurs de la langue. Le fait que les réponses l'ont pas encore fait, n'est peut-être un reflet de la clarté de la question, mais pas l'intention - pour ce que ça vaut, c'était ma lecture, mais je n'ai pas l'expertise pour répondre.
- Maintenant, nous avons une réponse de Eric Lippert. Vous voudrez peut-être repenser votre décision au sujet de la accepté de répondre. C'est Noël, alors peut-être que vous avez accepté la réponse trop tôt.
- Êtes-vous ce qui implique que les décisions de conception ne sont jamais documentés et sont tout à fait inconnu à tout le monde? Il ne demande pas de SORTE que les utilisateurs de deviner, il leur demande d'une réponse - qui n'implique pas qu'il est demandé pour une deviner. Si les gens à répondre à une conjecture est sur eux, ce n'est pas lui. Et que l'OP a souligné, il y a des gens sur un débordement de pile qui n'a fait travailler sur C# et ont pris ces décisions.
- Il n'est pas ce qui implique que les décisions de conception ne sont jamais documenté. Il n'est pas non plus ce qui implique que la question n'est pas intéressant. Il dit que la question a probablement besoin d'une réponse de la part des auteurs eux-mêmes, et n'est donc pas adapté à ce qu', car il conduit à une spéculation sauvage, comme démontré ici. Eric Lippert obtient autant autorité que n'importe qui pourrait demander, ce qui économise de cette question.
- Eh bien, je suis en désaccord; I ne pas crois que la réponse doit venir des auteurs eux-mêmes, bien que leur réponse serait le meilleur résultat possible. De nombreuses questions peuvent conduire à une spéculation sauvage, mais c'est un problème de la answerers, pas la personne. Il ya beaucoup de gens qui postent des hypothèses de réponses, ce qui rend la réponse mauvais, pas la question.
- Le problème est que, oui, à moins que la justification est déjà documenté quelque part, il doit, mais la spéculation est amusant et qui ne veut pas partager sa propre? Si vous trouvez une façon de s'assurer que ces purs (ou "éduqués") suppositions sont fiable cueilli, dites-moi et nous allons faire fortune.
- Je suis plus intéressé de savoir si vous pouvez le faire dans tous langue et pourquoi vous voulez? Il est hideux et fait très peu de sens.
Vous devez vous connecter pour publier un commentaire.
Je ferai de mon mieux.
Comme d'autres réponses ont noté ce qu'il se passe ici, c'est le compilateur détecte qu'un expression est utilisé comme un déclaration. Dans de nombreuses langues -- C, JavaScript, et bien d'autres -, il est parfaitement légal pour utiliser une expression comme une déclaration.
2 + 2;
est légal dans ces langues, même si c'est une déclaration qui n'a pas d'effet. Certaines expressions ne sont utiles que pour leurs valeurs, certaines expressions ne sont utiles que pour leurs effets secondaires (comme un appel à un vide de retour de la méthode) et de certaines expressions, malheureusement, sont utiles pour les deux. (Comme incrément.)Point de l'être: les déclarations qui sont constituées uniquement d'expressions sont presque certainement des erreurs à moins que ces expressions sont généralement considérés comme plus utiles pour leurs effets secondaires que leurs valeurs. C# concepteurs souhaitaient trouver un terrain d'entente, en permettant à des expressions qui ont été généralement admis que le côté effectuer, tout en interdisant à ceux qui sont généralement considérés comme utiles pour leurs valeurs. L'ensemble des expressions qu'ils ont identifié en C# 1.0 ont été des augmentations, diminutions, les appels de méthode, de devoirs, et un peu controversée, constructeur des invocations.
De CÔTÉ: normalement Un pense à une construction de l'objet comme étant utilisée pour la valeur qu'il produit, pas pour les effets secondaires de la construction; à mon avis, permettant
new Foo();
est un peu un misfeature. En particulier, j'ai vu ce modèle dans le monde réel, code qui a provoqué un défaut de sécurité:Il peut être étonnamment difficile à repérer ce défaut si le code est compliqué.
Le compilateur fonctionne donc de détecter tous les états qui consistent en des expressions qui ne sont pas sur cette liste. En particulier, les expressions entre parenthèses sont identifiés comme juste que-expressions entre parenthèses. Ils ne sont pas sur la liste des admis que l'énoncé des expressions", de sorte qu'ils ne sont pas autorisées.
Tout cela est au service d'un principe de conception du langage C#. Si vous avez tapé
(x++);
vous ont probablement fait quelque chose de mal. C'est probablement une faute de frappe pourM(x++);
ou quelque chose juste. Rappelez-vous, l'attitude du compilateur C# de l'équipe n'est pas "pouvons-nous trouver un moyen de faire ce travail?" L'attitude du compilateur C# de l'équipe est "si plausible code ressemble à une probable erreur, nous allons informer le développeur". Les développeurs C# comme attitude.Maintenant, tout ce que dit, qu'il y a un peu étrange cas où la spécification C# ne implique ni l'état pur et simple que les parenthèses ne sont pas acceptées, mais le compilateur C# permet de toute façon. Dans presque tous ces cas, le mineur divergence entre le comportement et le permis de comportement est totalement inoffensif, de sorte que le compilateur les écrivains n'ont jamais fixe ces petits bugs. Vous pouvez lire à ce sujet ici:
Est-il une différence entre le retour myVar vs retour (mavar)?
... ? ... : ...
, où la solution est d'utiliserif
/else
à la place.)contineu;
.new Foo()
comme une déclaration, c'est un mauvais modèle de conception en général, bien qu'il soit possible de voir un petit nombre de situations dans lesquelles il pourrait être utile. Par exemple, imaginez si il y avait un moyen de créer un nouveauThread
(ou personnalisé filetée de l'objet) qui peut démarrer automatiquement, et donc pas besoin de fairenew Thread(...).Start();
, qui répond à la nécessité d'appeler quelque chose. Je ne peux pas immédiatement penser à un exemple, mais je ne serais pas surpris s'il y a quelque chose qui a une sortie utile dans le constructeur (bien sûr, il faudrait être capable de plus pour justifier la création d'un nouvel objet normalement).try { new Foo(null); } catch (ArgumentNullException)...
mais, évidemment, ces situations sont, par définition, pas de code de production. Il semble raisonnable qu'un tel code pourrait être écrit à affecter à une variable muette.Dans le Spécification du langage C#
De mettre des parenthèses autour d'une instruction crée une nouvelle mise entre parenthèses de l'expression. À partir de la spécification:
Depuis la mise entre parenthèses des expressions ne sont pas répertoriés comme une expression valide déclaration, il n'est pas une instruction valide selon les spécifications. Pourquoi les concepteurs ont choisi de faire de cette façon je vous laisse deviner mais mon pari est que les parenthèses ne aucun travail utile si l'intégralité de la déclaration est entre parenthèses:
stmt
et(stmt)
sont exactement les mêmes.OP
demande rien au sujet de la langue de conception. Il veut juste savoir pourquoi c'est une erreur. La réponse est: parce que ce n'est pas une instruction valide.dans la mesure où les crochets autour de la
i++
de la création/la définition d'une expression.. comme le message d'erreur dit.. un simple expression ne peut pas être utilisé comme une déclaration.pourquoi le langage a été conçu pour être de cette façon? afin de prévenir les bogues, ayant trompeuse expressions comme des états, qui ne produisent pas d'effets secondaires comme ayant le code de
la deuxième ligne n'a pas d'effet(mais vous ne pouvez pas avoir remarqué). Mais au lieu de le compilateur de l'enlever(car le code n'est pas nécessaire).il demande explicitement de le supprimer(si vous le savez ou l'erreur) OU le fixer dans le cas où vous avez oublié de saisir quelque chose.
modifier:
pour faire la partie sur bracked plus clair.. crochets en c# (en plus d'autres utilisations, comme la fonte et de l'appel de fonction), sont utilisées pour grouper des expressions, et le retour à une expression unique (faire de la sous-expressions).
à ce niveau de code qui n'staments sont autorisés.. donc
mais par l'aide de la bracked vous transformant en tant qu'expression
et ce
n'est pas valide car le compilateur cant asure que l'expression en tant qu'effet secondaire.(non sans encourir dans le problème de l'arrêt)..
j
variable de droit?j++;
déclaration est valable, mais en utilisant les crochets que vous diteslet me take this stement and turn it into an expression
.. et les expressions ne sont pas valides à ce point dans le code