Use string.Contains() with switch()
Asked Answered
O

12

90

I'm doing an C# app where I use

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

There would be any way to change to switch() the if() statements?

Optimal answered 24/8, 2011 at 12:42 Comment(0)
S
4

You can do the check at first and then use the switch as you like.

For example:

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

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

Then

switch(str)
{
  case "test1" : {} break;
  case "test2" : {} break;
  default : {} break;
}
Skullcap answered 24/8, 2011 at 13:15 Comment(2)
I don't understand this answer.Staggers
In the scenario of str = "test1,test2"; case "test1" will not work.Plato
C
164

Correct final syntax for [Mr. C]s answer.

With the release of VS2017RC and its C#7 support it works this way:

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

You should take care of the case ordering as the first match will be picked. That's why "test2" is placed prior to test.

Corticosterone answered 2/1, 2017 at 14:11 Comment(6)
+1 This works perfectly now. And to anyone wondering you can access the value of the case via the "x" variable in this scenario.Judejudea
Also, you can use any var name-except-the one in the switch statement to evaluate. Then, you can refer to the original variable/expression in the code that follows.Advice
@Patrick, can you clarify what you mean by the "x" variable? Sorry I'm sure it's obvious.Prescind
I feel so dumb asking about this simple answer, but isn't "break" also mandatory in C# case statements?Prescind
In case statements you can leave the break if you use return.Corticosterone
I believe this should be marked the answer.Slung
T
43

This will work in C# 8 using a switch expresion

var message = "Some test message";

message = message switch
{
    string a when a.Contains("test") => "yes",
    string b when b.Contains("test2") => "yes for test2",
    _ => "nothing to say"
};

For further references https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/switch-expression

Transmissible answered 3/8, 2020 at 22:17 Comment(2)
I find switch expressions a very strange syntax that is hard to remember. Always find myself looking it up if I haven't used it in a few months...Bathhouse
it harder to write but easier to read.. Worth the effort.Foretop
T
36

Nope, switch statement requires compile time constants. The statement message.Contains("test") can evaluate true or false depending on the message so it is not a constant thus cannot be used as a 'case' for switch statement.

Tetrad answered 24/8, 2011 at 12:43 Comment(4)
So I only can use if()? That's pretty messy :(Optimal
@zad0xsis: Do you have a lot of these? If so, you could potentially abstract the idea somewhat...Frottage
yeah I've got a lot of if() :(Optimal
It's worth noting - this will change with C# 7. Patterns can be used in case clauses. As of this writing, this feature is available in Visual Studio 15 Preview 4. blogs.msdn.microsoft.com/dotnet/2016/08/24/…Aludel
C
34

If you just want to use switch/case, you can do something like this, 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;
    }

But if the quantity of keys is a big, you can just replace it with dictionary, like this:

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`... 
 }
Chronogram answered 24/8, 2011 at 13:14 Comment(2)
I removed <string> from string sKeyResult = keys.FirstOrDefault<string>(s=>message.Contains(s)); and still works fine.Inoperative
This is truly thinking outside the box. Nice!Fuddyduddy
M
25

Simple yet efficient with c#

 string sri = "Naveen";
    switch (sri)
    {
        case var s when sri.Contains("ee"):
           Console.WriteLine("oops! worked...");
        break;
        case var s when sri.Contains("same"):
           Console.WriteLine("oops! Not found...");
        break;
    }
Mousebird answered 29/9, 2020 at 10:36 Comment(2)
If you don't need the value of var s (as you don't in your example) you can use var _ to discard it.Speedboat
Similarly to the answer above when you don't need the value of var s, you can use not null to discard it.Assertive
D
7
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; 
}
Drove answered 8/1, 2019 at 9:44 Comment(0)
S
4

You can do the check at first and then use the switch as you like.

For example:

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

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

Then

switch(str)
{
  case "test1" : {} break;
  case "test2" : {} break;
  default : {} break;
}
Skullcap answered 24/8, 2011 at 13:15 Comment(2)
I don't understand this answer.Staggers
In the scenario of str = "test1,test2"; case "test1" will not work.Plato
P
3

Faced with this issue when determining an environment, I came up with the following one-liner:

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

That way, if it can't find anything in the provided string that matches the "switch" conditions, it gives up and returns null. This could easily be amended to return a different value.

It's not strictly a switch, more a cascading if statement but it's neat and it worked.

Paedo answered 17/5, 2017 at 9:26 Comment(0)
A
2

Some custom swtich can be created like this. Allows multiple case execution as well

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 });
    }
}

Call like this

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);
Amoakuh answered 24/8, 2011 at 13:44 Comment(0)
O
1

Stegmenn nalied it for me, but I had one change for when you have an IEnumerable instead of a string = message like in his example.

private static string GetRoles(IEnumerable<External.Role> roles)
{
    string[] switchStrings = { "Staff", "Board Member" };
    switch (switchStrings.FirstOrDefault<string>(s => roles.Select(t => t.RoleName).Contains(s)))
    {
        case "Staff":
            roleNameValues += "Staff,";
            break;
        case "Board Member":
            roleNameValues += "Director,";
            break;
        default:
            break;
    }
}
Onida answered 28/4, 2020 at 14:0 Comment(0)
A
0

This will work in C# 7. As of this writing, it has yet to be released. But if I understand this correctly, this code will work.

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/

Aludel answered 15/12, 2016 at 18:42 Comment(4)
No, this does not work. Contains does not exist in the current context.Dough
I cannot see your example on the link provided.Treachery
Does not work, you should test it first before sharing your answer. See Lakedaimon's solution for the correct syntax.Salaried
This is pretty close. Mr. C is correct in his answer. "This will work in C# 7" The syntax for this to work is slightly off though... Review Lakedaimon's answer for correct syntax.Judejudea
F
-6
switch(message)
{
  case "test":
    Console.WriteLine("yes");
    break;                
  default:
    if (Contains("test2")) {
      Console.WriteLine("yes for test2");
    }
    break;
}
Frivolous answered 28/12, 2019 at 7:28 Comment(2)
Hi, welcome to stack overflow. For a useful answer explain why this is an answer to the question.Mohenjodaro
in C# switch condition is not powerful as KOTLIN so if you want to implement String.contains() in condition state of switch I think we have to separate our condition in default partFrivolous

© 2022 - 2024 — McMap. All rights reserved.