IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Comparaison dans un switch


Sujet :

C#

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2018
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2018
    Messages : 6
    Points : 6
    Points
    6
    Par défaut Comparaison dans un switch
    salut tout le monde
    je veux executer des conditions mais sans passer par le long chemin des if et else if. Alors jai decide d'utiliser le switch mais sa ne prend pas.
    Sa me dit que j'essais deffectuer une conversion entre un double et un typ bool du coup affiche une erreur et je sais pas comment faire
    merci bien!
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
      double betrag = 15000;
     
                switch (betrag)
                {
                    case  < 500:
     
                        Console.WriteLine("Es tut mir leid aber für diesen Einkauf bekommen Sie kein Rabatt!");
                        break;
     
                    case ( betrag >= 2000 && < 5000):
     
                        Console.WriteLine("für diesen Einkauf erhalten Sie 5% Rabatt");
                        break;
     
                    case (betrag >=500 && < 2000):
                        Console.WriteLine("Für diesen Einkauf erhalten Sie 2% Rabatt");
                        break;
     
                    case  >= 5000:
                        Console.WriteLine("Für diesen Einkauf erhalten Sie 10% Rabatt");
                        break;
                }

  2. #2
    Membre chevronné
    Avatar de PixelJuice
    Homme Profil pro
    Ingénieur .NET & Game Designer
    Inscrit en
    Janvier 2014
    Messages
    652
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur .NET & Game Designer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2014
    Messages : 652
    Points : 2 180
    Points
    2 180
    Par défaut
    Bonjour,

    En effet ton switch ne veut que des valeurs de type double. Le problème c'est que :

    est une condition, qui est considérée comme un bool.

    Du coup même si tu pouvais faire ça, tu serais limité au fait qu'il n'y aurait que deux case possible : true ou false. Quelle que soit la condition.

    Il te faut passer par un if / else.

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2018
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2018
    Messages : 6
    Points : 6
    Points
    6
    Par défaut
    Donc le c# ne le permet pas alors !!
    C’est bizarre

  4. #4
    Membre chevronné
    Avatar de PixelJuice
    Homme Profil pro
    Ingénieur .NET & Game Designer
    Inscrit en
    Janvier 2014
    Messages
    652
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur .NET & Game Designer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2014
    Messages : 652
    Points : 2 180
    Points
    2 180
    Par défaut
    Citation Envoyé par junior1998 Voir le message
    Donc le c# ne le permet pas alors !!
    C’est bizarre
    Non il ne le permet pas je pense, et les langages ou il est possible de le faire, je lis qu'il est fortement conseillé de passer par un if / else quand même, pour la lisibilité, etc ...

    Pourquoi bizarre ? Un switch case est fait pour des cas d'utilisation très simples. Si tu as besoin de complexité, alors il te faudra passer par autre chose.

    Personnellement, j'utilise très peu, voir pas du tout les switch case, hormis si il me faut évaluer des enums.

  5. #5
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 761
    Points : 10 543
    Points
    10 543
    Billets dans le blog
    21
    Par défaut
    Bonjour,

    On peut arriver à quelque chose d'approchant, en utilisant le pattern matching, qui permet de préciser une condition :

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    double betrag = 15000;
     
    switch (betrag)
    {
        case double d when d < 500:
     
            Console.WriteLine("Es tut mir leid aber für diesen Einkauf bekommen Sie kein Rabatt!");
            break;
     
        case double d when (d >= 2000 && d < 5000):
     
            Console.WriteLine("für diesen Einkauf erhalten Sie 5% Rabatt");
            break;
     
        case double d when (d >= 500 && d < 2000):
            Console.WriteLine("Für diesen Einkauf erhalten Sie 2% Rabatt");
            break;
     
        case double d when d >= 5000:
            Console.WriteLine("Für diesen Einkauf erhalten Sie 10% Rabatt");
            break;
    }

    Attention, c'est une nouveauté disponible uniquement depuis C# 7.

  6. #6
    Expert confirmé
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    Mars 2005
    Messages
    2 752
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste programmeur Delphi / C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 2 752
    Points : 5 458
    Points
    5 458
    Par défaut
    Ou sinon, une manière ressemblante réalisable à partir du framework 3.5

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Double number = 2018;
     
    var choices = new Dictionary<Func<Double, Boolean>, Action>
    {
        { x => x < 500 , () => Console.WriteLine("0-499") },
        { x => x < 2000 , () => Console.WriteLine("500-1999") },
        { x => x < 5000 , () => Console.WriteLine("2000-4999") },
        { x => x < Double.MaxValue , () => Console.WriteLine("5000+") }
    };
     
    choices.First(it => it.Key(number)).Value();

  7. #7
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 177
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 177
    Points : 25 125
    Points
    25 125
    Par défaut
    Citation Envoyé par PixelJuice Voir le message
    Pourquoi bizarre ? Un switch case est fait pour des cas d'utilisation très simples. Si tu as besoin de complexité, alors il te faudra passer par autre chose.
    j'aurais tendance à dire non
    le switch de c# est fait pour des cas d'utilisation très simple, mais dans d'autres langages pas forcément
    en vb.net on peut faire
    Code vb.net : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    select case true ' conditions volontairements hétéroclites pour montrer l'étendue (non exhaustive)
      case d > 50 andalso d < 200
      case typeof var3 is IMachin
      case coll.firstordefault(condition …) isnot Nothing
      case MaFctQuiReturnUnBool(var4)
    end select
    et parfois c'est bien pratique de pouvoir faire des choses complexes avec peu de code qui plus est lisible (en plus vb.net n'a pas besoin de break à chaque case)
    le switch par typage de c# amène un peu de souplesse et c'est déjà bien mais pas encore assez je pense ...

  8. #8
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 761
    Points : 10 543
    Points
    10 543
    Billets dans le blog
    21
    Par défaut
    Citation Envoyé par popo Voir le message
    Ou sinon, une manière ressemblante réalisable à partir du framework 3.5
    Pas con et très astucieux !

    Par contre, il faut bien avoir des bornes qui ne se recoupent pas. S'agissant d'un dictionnaire, l'ordre dans lequel les clés sont énumérées est indéfini.

    Donc ici, je changerai le code en :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Double number = 2018;
     
    var choices = new Dictionary<Func<Double, Boolean>, Action>
    {
        { x => x < 500 , () => Console.WriteLine("0-499") },
        { x => 500 <= x && x < 2000 , () => Console.WriteLine("500-1999") },
        { x => 2000 <= x && x < 5000 , () => Console.WriteLine("2000-4999") },
        { x => 500 <= x && x < Double.MaxValue , () => Console.WriteLine("5000+") }
    };
     
    choices.First(it => it.Key(number)).Value();

  9. #9
    Max
    Max est déconnecté
    Expert éminent sénior

    Avatar de Max
    Homme Profil pro
    Artisan développeur
    Inscrit en
    Mai 2007
    Messages
    2 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Artisan développeur
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2007
    Messages : 2 954
    Points : 14 933
    Points
    14 933
    Par défaut
    Citation Envoyé par François DORIN Voir le message
    Pas con et très astucieux !
    Très astucieux mais peut-être un peu too much dans ce contexte (la discussion a le tag [Débutant])

  10. #10
    Expert confirmé
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    Mars 2005
    Messages
    2 752
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste programmeur Delphi / C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 2 752
    Points : 5 458
    Points
    5 458
    Par défaut
    Citation Envoyé par François DORIN
    Pas con et très astucieux !
    Effectivement, c'est une vielle ruse que je n'avais pas utilisé depuis longtemps.
    Je l'ai tapé de mémoire et tu as tout à fait raison sur la particularité du dictionnaire.
    Petite rectification sur la dernière condition toutefois, il manque un zéro.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        { x => 5000 <= x && x < Double.MaxValue , () => Console.WriteLine("5000+") }

    Citation Envoyé par Max
    Très astucieux mais peut-être un peu too much dans ce contexte (la discussion a le tag [Débutant])
    Effectivement, c'est un poil avancé pour un débutant, ça nécessite donc une explication.

    Tout d'abord l'instruction est basé sur un dictionnaire (un couple clé-valeur dont la clé est unique mais pas forcément triée).
    Ici, la clé et la valeur sont des délégués (en quelque sorte, des pointeurs vers des fonction).
    Dans ce cas, la clé sera donc un pointeur vers une fonction prenant en paramètre un Double et renvoyant un Booléen.
    Et la valeur sera un pointeur vers une fonction ne prenant pas de paramètre et ne retournant aucune valeur.

    Le dictionnaire contient donc quatre pairs clé-valeur

    Chaque clé est composé d'une expression lambda définissant le corps du premier délégué.
    Comme le premier paramètre est un double, je l'ai appelé x, et comme le résultat est un booléen, seul le test logique (la comparaison du paramètre en entrée) est nécessaire.

    Chaque valeur est composé d'une expression lambda définissant le corps du second délégué.
    Puisque qu'il n'y a pas de paramètre en entrée, on place "()", puis le corps de l'action à réaliser (ici Console.WriteLine).

    J'aurais pu déclarer les fonction une à une et écrire ceci, mais ça aurait été plus long et on aurait pas eu toutes les informations visibles d'un coup.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    class Program
    {
        static void Main(string[] args)
        {
            Double number = 2018;
     
            var choices = new Dictionary<Func<Double, Boolean>, Action>
            {
                { TestInf500, WriteInf500  },
                { TestBetwen500And1999, WriteBetween500And1999 },
                { TestBetwen2000And4999 , WriteBetween2000And4999},
                { TestSup5000 , WriteSup5000 }
            };
     
            choices.First(it => it.Key(number)).Value();
     
            Console.ReadKey();
     
     
        }
     
        public static Boolean TestInf500(Double x)
        {
            return x < 500;
        }
     
        public static Boolean TestBetwen500And1999(Double x)
        {
            return 500 <= x && x < 2000;
        }
     
        public static Boolean TestBetwen2000And4999(Double x)
        {
            return 2000 <= x && x < 5000;
        }
     
        public static Boolean TestSup5000(Double x)
        {
            return 5000 <= x && x < Double.MaxValue;
        }
     
        public static void WriteInf500()
        {
            Console.WriteLine("0-499");
        }
     
        public static void WriteBetween500And1999()
        {
            Console.WriteLine("500-1999");
        }
     
        public static void WriteBetween2000And4999()
        {
            Console.WriteLine("2000-4999");
        }
     
        public static void WriteSup5000()
        {
            Console.WriteLine("5000+");
        }
    }
    La ligne "choices.First(it => it.Key(number)).Value()" est composé comme ceci :
    choice.First est une méthode Linq recherchant la première clé-valeur répondant aux critères passés via l'expression lambda.
    it => it.Key(number) est mon expression lambda, elle signifie que parmi les clé du dictionnaire, je dois rechercher le délégué dont le retour matchera.
    Pour la valeur 2018, le premier (et le seul) délégué qui répond true est le troisième.
    .Value() est appliqué sur la pair clé-valeur trouvé par First, et me permet de récupérer la valeur de cette pair et donc le délégué qui affiche l'information dans la console.

    J'espère avoir été suffisamment clair.

Discussions similaires

  1. opérateur de comparaison dans un switch
    Par new_wave dans le forum Langage
    Réponses: 2
    Dernier message: 08/12/2008, 10h28
  2. Position de default et case dans un switch
    Par Glutinus dans le forum C
    Réponses: 16
    Dernier message: 11/09/2006, 22h17
  3. Problème dans un "switch"
    Par belzeluc dans le forum C++
    Réponses: 4
    Dernier message: 04/06/2006, 12h13
  4. Une boucle for dans un switch case?
    Par Death83 dans le forum Langage
    Réponses: 4
    Dernier message: 26/04/2006, 14h05
  5. Réponses: 27
    Dernier message: 12/01/2006, 11h04

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo