Accueil > CSharp > C# quizz ?

C# quizz ?

Un petit bout de code qui m’a causé un drôle de bug.

A la première lecture cela m’a même paru impossible et pourtant…

 

bool Test()
{
    return IsNetworkAvailable || ...;
}


IsNetworkAvailable retourne “true” et pourtant Test() renvoie “false” !!

Je vous laisse remplir l’instruction qui suit le || Sourire

Mitsu

Catégories :CSharp
  1. Nicolas Boonaert
    24/10/2016 à 04:53

    Au hasard, un truc ayant rapport avec l’ordre d’interprétation et l’associativité des opérateurs… Donc un truc comme :
    >> return IsNetworkAvailable || IsNetworkAvailable ? false : true;

    En référence :
    https://msdn.microsoft.com/en-us/library/2bxt6kc4.aspx?f=255&MSPPError=-2147217396

  2. 24/10/2016 à 13:47

    J’ai une solution, mais peut-être pas celle qui était attendue…

    
    bool Test()
    {
        return IsNetworkAvailable || new Foo();
    }
    
    class Foo
    {
        public static bool operator true(Foo f)
        {
            return false;
        }
        
        public static bool operator false(Foo f)
        {
            return true;
        }
        
        public static implicit operator Foo(bool b)
        {
            return new Foo();
        }
    
        public static implicit operator bool(Foo f)
        {
            return false;
        }
    
        public static Foo operator |(Foo x, Foo y)
        {
            return new Foo();
        }
    }
    
  3. 24/10/2016 à 18:34

    Yes Nicolas Boonaert !
    En effet, il s’agit d’un problème de priorité d’évaluation d’une expression. C’est valable dans une expression mathématique et dans tous les langages de programmation.
    Une expression combine des opérandes et des opérateurs. S’il y a plusieurs opérateurs, le compilateur/interpréteur ordonne les calculs suivant un ordre de priorité prédéfini. Par exemple les multiplications sont évaluées avant les additions.

    Ici c’est une expression booléenne. En C# le OU (||) est d’une priorité inférieure au ET (&&).
    Le seul moyen de court-circuiter le « true || », y compris la simplification du compilateur, c’est que la suite embarque un opérateur de plus faible priorité !
    Et c’est le cas de l’opérateur ternaire « ? » ce qui est logique puisqu’il exploite un booléen comme premier paramètre (à sa gauche).

    Ainsi comme le montre Nicolas, une expression telle que la suivante priorise le OU. Le ? est donc le dernier à exprimer sa logique.

    return (IsNetworkAvailable || whatever()) ? true : false;

  4. Nicolas Boonaert
    25/10/2016 à 08:18

    Quand ça t’arrive dans un code métier complexe, tu y vas à la main pour debug des conditions de filtres et là tu ajoutes des parenthèses partout comme un psychopathe.

    Pour ça que j’aime bien l’utilisation avec parcimonie des opérateurs ternaires, de même que l’opérateur « ?. » (Null-conditional Operators) introduit avec C#6, il faut néanmoins rester prudent !

    A+ Mitsu

  1. No trackbacks yet.

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s

%d blogueurs aiment cette page :