4 votes

expressions booléennes, pourquoi seulement deux termes ?

Étant donné qu'il est possible d'écrire

a = b = c = 2;

Il serait également souhaitable qu'au lieu de

bool allTwo = a == 2 && b == 2 && c == 2;

pour écrire à la place

bool allTwo = a == b == c == 2;

Mais je ne peux pas car a == b évalue un booléen qui ne peut pas être comparé à un entier.

Y a-t-il une raison de conception du langage qui explique cette façon de procéder ?

8voto

Pete Kirkham Points 32484

Le type de l'expression a == b est booléen, il faudrait donc soit enfreindre la règle selon laquelle une expression signifie la même chose quel que soit son contexte, soit avoir des opérateurs == n-aires pour que a == b == c est analysé comme (== a b c) plutôt que (== (== a b) c) . Ce qui signifie que vous devez avoir (a == b) == c pour comparer le booléen c au résultat de (a == b) ce qui est correct, mais pas le style de grammaire C simple dont C# est la tradition.

5voto

Bob Points 4773

Eh bien, l'expression c == 2 renverrait true , de sorte que b serait comparée à true au lieu de 2.

Edit : Il est très probable qu'il ait été implémenté de cette manière car c'est ainsi que les langages de style C gèrent les expressions booléennes. Ils auraient dû faire une exception spéciale pour les termes multiples et l'implémenter différemment, alors qu'avec l'opérateur d'affectation, c'est plus simple : l'expression la plus à droite est évaluée à une valeur qui peut logiquement être appliquée à l'expression suivante dans la chaîne. Il semble que les concepteurs aient choisi l'approche la plus simple.

3voto

De mon point de vue, c'est une question de clarté. Si la décision ne dépendait que de moi, j'examinerais comment l'ajout d'une telle caractéristique du langage pourrait ajouter trop d'ambiguïté quant à la manière dont les expressions compliquées sont évaluées. Est-ce que a == b == c est différent de (a == b) == c dans certaines situations ? Que se passe-t-il si je veux vraiment comparer c au résultat booléen de a == b plutôt que de comparer c à b ? Dans la plupart des cas, le compilateur peut probablement déterminer la comparaison appropriée, mais si c est implicitement convertible en bool, bien que cela soit peu probable, il peut être impossible de le savoir.

Personnellement, je ne suis pas sûr que cela vaille la peine. Bien que la syntaxe ne soit pas aussi agréable, vous pouvez créer votre propre fonction utilitaire pour comparer l'égalité de plusieurs objets, comme ci-dessous :

    public static bool Equals(this object x, params object[] y)
    {
        for (int i = 0; i < y.Length; i++)
        {
            if (!object.Equals(x, y[i]))
                return false;
        }
        return true;
    }

Vous pouvez alors l'utiliser comme suit :

        if (a.Equals(b, c, d, e, f, g))
        {
            // ...
        }

2voto

Nelson Rothermel Points 3538

Je n'arrive pas à retrouver la citation, mais je pense que c'est Eric Lippert ( ?) qui l'a le mieux exprimée : ne pas mettre en œuvre une fonctionnalité est gratuit. Voir aussi http://blog.ryjones.org/2005/07/12/product-development/ y http://blog.ryjones.org/2005/07/12/product-development/

Ils ont de nombreuses fonctionnalités à mettre en œuvre et je ne peux pas imaginer que quelque chose de non standard comme celui-ci, dont la valeur est discutable, soit une priorité élevée. Je ne dis pas que cela n'a pas de valeur, mais cela pourrait mener à la confusion, ne serait probablement pas utilisé très souvent, etc. Je pense que a1ex07 a également raison. Cela devrait être un cas particulier puisque cela ne peut plus être géré de manière générique (== renvoie toujours un booléen, etc.).

Il est possible de faire la même chose avec LINQ, mais la syntaxe est un peu plus compliquée et nécessite l'allocation d'un tableau quelconque :

bool allTwo = new int[] { a, b, c }.All(i => i == 2);

Vous pouvez le faire à l'envers et vérifier si l'un d'entre eux != 2 :

bool allNotTwo = new int[] { a, b, c }.Any(i => i != 2);

Dans les deux cas, le système s'arrête dès que l'un d'eux n'est pas valide, ce qui permet souvent de ne pas parcourir toute la liste.

Editer : Voici un autre point : Le langage C# présente-t-il trop de caractéristiques ?

quelque chose de nouveau a été fait très u dans la langue

1voto

a1ex07 Points 23965

Faire ce que l'on veut, operator == doit renvoyer un objet. Dans ce cas, nous aurons un autre problème - il nous faut maintenant une conversion implicite de tout objet en booléen. Une telle conversion créera également des problèmes supplémentaires.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X