web-dev-qa-db-fra.com

Pourquoi une instruction if fonctionne-t-elle mais pas une instruction switch?

J'essaie de créer une instruction switch à l'aide de l'index de caractère d'une chaîne et d'un énum à l'aide de l'encapsuleur this pour obtenir la valeur de l'énum sélectionné à partir d'une description. Cela vous permet de stocker une chaîne avec une valeur enum.

Voici ma déclaration if:

if (msgComingFromFoo[1] == Convert.ToChar(Message.Code.FOO_TRIGGER_SIGNAL.EnumDescriptionToString()))
{
    //foo
}

et voici ma déclaration switch:

switch (msgComingFromFoo[1])
{
    case Convert.ToChar(Message.Code.FOO_TRIGGER_SIGNAL.EnumDescriptionToString()):
        break;
}

Pourquoi accepte-t-il l'instruction if et non switch? J'ai essayé de le convertir en caractère car je sélectionne un index dans une chaîne, mais malheureusement cela n'a pas fonctionné.

Mise à jour:

Voici le Message.Code Enum

public class Message
{
    public enum Code
    {
        [Description("A")]
        FOO_TRIGGER_SIGNAL
    }
}

Comme vous pouvez le constater, la description doit être affectée à l'énumération, pas à la valeur 0. L'utilisation de Message.Code.FOO_TRIGGER_SIGNAL.EnumDescriptionToString() du wrapper mentionné renvoie A et non pas 0


Erreur:

Une valeur constante est attendue

39
AndrewE

Vous ne pouvez pas avoir d'expressions dans le cas (avant C # 7), mais vous pouvez dans le commutateur, donc cela fonctionnera:

switch (ConvertToMessageCode(msgComingFromFoo[1]))
{
    case Message.Code.FOO_TRIGGER_SIGNAL:
        break;
}

Où vous devrez écrire ConvertToMessageCode pour effectuer la conversion nécessaire en Message.Code enum. ConvertToMessageCode résume simplement les détails de la conversion. Vous constaterez peut-être que vous n'avez pas besoin d'une méthode distincte, mais que vous pouvez vous contenter du code en ligne dans l'instruction switch, par exemple une conversion.

53
Polyfun

Un case dans une instruction switch doit faire référence à une valeur constante. Vous ne pouvez pas évaluer une expression dans un case.

27
Code-Apprentice

C’est vraiment ce n’est pas une bonne réponse car cela ne sert qu’à préciser les réponses précédentes. Ne l'acceptez pas (ne votez pas non plus au-dessus de toute réponse raisonnable). Je l'écris comme une réponse uniquement, car un commentaire ne correspond pas à cette explication.


Tu as essayé:

switch (msgComingFromFoo[1])
{
    case Convert.ToChar(Message.Code.FOO_TRIGGER_SIGNAL.EnumDescriptionToString()):
        break;
}

Cela ne fonctionne pas car le cas n'est pas constant. Comme suggéré, la meilleure solution consiste à convertir le msgComingFromFoo[1] chaîne en arrière à une valeur enum afin que vous puissiez basculer sur l'énumération et utiliser les constantes enum dans les cas de commutation.

Si cela n’est pas possible, vous pouvez toujours basculer sur les constantes de chaîne. Cependant, ceci est sujet aux erreurs et va à l'encontre du but d'utiliser enums en premier lieu.

switch (msgComingFromFoo[1])
{
    case "A":
        break;
}

Autre remarque: rappelez-vous que les tableaux sont indexés à zéro. Vous basculez actuellement sur l'élément second, pas sur le premier. Utilisation msgComingFromFoo[0] pour le premier élément.

6
Jochem Kuijpers

Pour ajouter à la réponse de @ code-apprentis.

Si vous trouvez que l'instruction if devient trop longue ou comporte plusieurs conditions dans if else's. Vous pouvez envisager de refactoriser le code et d'encapsuler votre logique dans un objet et d'utiliser le modèle de visiteur pour contrôler le travail à effectuer.

Quelque chose comme:

public interface IMessageLogic 
{
   void ProcessMessage()
}

public class TriggerSignal : IMessageLogic 
{
   public void ProcessMessage() 
   {
       // Do trigger stuff
   }
}

public class FooMessage : IMessageLogic 
{
   public void ProcessMessage() 
   {
       // Do foo stuff
   }
}

public class MessageHandler
{
    public void HandleMessage(IMessageLogic messageLogic)
    {
        messageLogic.ProcessMessage();
    }
}

public static void Main()
{
    IMessageLogic messageLogic = GetMessage();
    var handler = new MessageHandler();

    handler.HandleMessage(messageLogic);
 }

modèle de visiteur

5
Victor Procure