简体   繁体   中英

Can I use the recent c# addition 'case when' clause to use StartsWith in a switch?

case when is fairly new so many answers don't touch upon it. The MSDN example is about casting the object, not using the original string.

switch (catName)
{
    case string c when c.StartsWith("Fluffy"):
        // DoSomething
        break;
}

This seems to work, it'd be nicer if you could omit the string c part and just do when catName instead. But then multiple cases don't work:

switch (catName)
{
    case string c when c.StartsWith("Fluffy"):
    case string c when c.StartsWith("Mr"):
        // DoSomething
        break;
}

Because you can't declare two string c . So you could change the second one, but you'd end up with a list of string a, string b, string c etc which doesn't seem very nice.

The ideal way would of course be something like:

switch (catName)
{
    case when catName.StartsWith("Fluffy"):
        ...
        break;
}

Is there an elegant way to solve this, or is it simply better to use an if..else if method?

Edit:

My favourite solution is suggested by kofifus in the comments:

    string catName = "Fluffy";
    switch (catName)
    {
        case {} when catName.StartsWith("Fluffy"):
        case {} when catName.StartsWith("Mr"):
            Console.WriteLine(catName);
            break;
        default:
            Console.WriteLine("Name does not start with Mr or Fluffy.");
            break;
    }

I know you said two different strings isn't nice, but this looks very readable to me, is there really a problem with doing it like this:

    string catName = "Fluffy";
    switch (catName)
    {
        case string c when c.StartsWith("Fluffy"):
        case string d when d.StartsWith("Mr"):
            Console.WriteLine(catName); 
            break;  
        default:
            Console.WriteLine("Name does not start with Mr or Fluffy.");  
            break;  
    }

Alternatively, based on the 'Reference' link in Krustys answer you could do it like this:

    string catName = "Noodle";
    switch (catName)
    {
        case string c when (c.StartsWith("Fluffy") || c.StartsWith("Mr")):
            Console.WriteLine(catName); 
            break;  
        default:
            Console.WriteLine("Name does not begin with Mr or Fluffy.");    
            break;  
    }

No you can't, because you are using the pattern matching into the switch statement and the type is evaluated at compile time:

expr has a compile-time type that is a base class of type

Anyway, you can use the same variable names because their scope is local. Reference

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM