web-dev-qa-db-fra.com

Utilisez string.Contains () avec switch ()

Je fais une application C # où j'utilise 

if ((message.Contains("test")))
{
   Console.WriteLine("yes");
} else if ((message.Contains("test2"))) {
   Console.WriteLine("yes for test2");
}

Y aurait-il un moyen de changer en switch() les instructions if()?

25
pmerino

Vous pouvez faire la vérification dans un premier temps, puis utiliser le commutateur à votre guise.

Par exemple:

string str = "parameter"; // test1..test2..test3....

if (!message.Contains(str)) return ;

Ensuite

switch(str)
{
  case "test1" : {} break;
  case "test2" : {} break;
  default : {} break;
}
11
shenhengbin

Non, l'instruction switch nécessite des constantes de temps de compilation. L'instruction message.Contains("test") peut évaluer true ou false en fonction du message. Il ne s'agit donc pas d'une constante. Par conséquent, elle ne peut pas être utilisée comme "cas" pour une instruction switch.

33
Teoman Soygul

Si vous voulez juste utiliser switch/case, vous pouvez faire quelque chose comme ceci, pseudo-code: 

    string message = "test of mine";
    string[] keys = new string[] {"test2",  "test"  };

    string sKeyResult = keys.FirstOrDefault<string>(s=>message.Contains(s));

    switch (sKeyResult)
    {
        case "test":
            Console.WriteLine("yes for test");
            break;
        case "test2":
            Console.WriteLine("yes for test2");
            break;
    }

Mais si la quantité de clés est grande, vous pouvez simplement la remplacer par dictionnaire, comme ceci: 

static Dictionary<string, string> dict = new Dictionary<string, string>();
static void Main(string[] args)
{
    string message = "test of mine";      

    // this happens only once, during initialization, this is just sample code
    dict.Add("test", "yes");
    dict.Add("test2", "yes2"); 


    string sKeyResult = dict.Keys.FirstOrDefault<string>(s=>message.Contains(s));

    Console.WriteLine(dict[sKeyResult]); //or `TryGetValue`... 
 }
25
Tigran

Corrigez la syntaxe finale pour [Mr. C] s réponse.

Avec la sortie de VS2017RC et son support C # 7, cela fonctionne comme suit:

switch(message)
{
    case string a when a.Contains("test2"): return "no";
    case string b when b.Contains("test"): return "yes";
}

Vous devez vous occuper de la commande des cas car le premier match sera choisi. C'est pourquoi "test2" est placé avant le test.

18
Lakedaimon

Cela fonctionnera en C # 7. A ce jour, il n’a pas encore été publié. Mais si je comprends bien, ce code fonctionnera.

switch(message)
{
    case Contains("test"):
        Console.WriteLine("yes");
        break;
    case Contains("test2"):
        Console.WriteLine("yes for test2");
        break;
    default:
        Console.WriteLine("No matches found!");
}

Source: https://blogs.msdn.Microsoft.com/dotnet/2016/08/24/whats-new-in-csharp-7-0/

5
Mr. C

Certains swtich personnalisés peuvent être créés comme ceci. Permet également l'exécution de plusieurs cas

public class ContainsSwitch
{

    List<ContainsSwitch> actionList = new List<ContainsSwitch>();
    public string Value { get; set; }
    public Action Action { get; set; }
    public bool SingleCaseExecution { get; set; }
    public void Perform( string target)
    {
        foreach (ContainsSwitch act in actionList)
        {
            if (target.Contains(act.Value))
            {
                act.Action();
                if(SingleCaseExecution)
                    break;
            }
        }
    }
    public void AddCase(string value, Action act)
    {
        actionList.Add(new ContainsSwitch() { Action = act, Value = value });
    }
}

Appelle comme ça

string m = "abc";
ContainsSwitch switchAction = new ContainsSwitch();
switchAction.SingleCaseExecution = true;
switchAction.AddCase("a", delegate() { Console.WriteLine("matched a"); });
switchAction.AddCase("d", delegate() { Console.WriteLine("matched d"); });
switchAction.AddCase("a", delegate() { Console.WriteLine("matched a"); });

switchAction.Perform(m);
2
hungryMind

Confronté à ce problème lors de la détermination d'un environnement, j'ai proposé le one-liner suivant:

string ActiveEnvironment = localEnv.Contains("LIVE") ? "LIVE" : (localEnv.Contains("TEST") ? "TEST" : (localEnv.Contains("LOCAL") ? "LOCAL" : null));

Ainsi, s'il ne trouve rien dans la chaîne fournie qui corresponde aux conditions de "commutation", il abandonne et renvoie null. Cela pourrait facilement être modifié pour renvoyer une valeur différente.

Ce n'est pas strictement un commutateur, mais plutôt une instruction if en cascade, mais elle est soignée et a fonctionné.

2
0xFF
string message = "This is test1";
string[] switchStrings = { "TEST1", "TEST2" };
switch (switchStrings.FirstOrDefault<string>(s => message.ToUpper().Contains(s)))
{
    case "TEST1":
        //Do work
        break;
    case "TEST2":
        //Do work
        break;
    default:
        //Do work
        break; 
}
0
Stegmann