我可以将switch语句与string.Contains()一起使用吗?

时间:2015-10-05 18:35:26

标签: c# string switch-statement contains

我有一个方法使用一长串if / elseif语句(大约10-15),我明白当你通过大约5 if / else if语句时,最好使用一个开关。话虽这么说,我不确定我可以在我的情况下使用switch语句,因为我的if / else if语句依赖于测试字符串,而不是相等,而是使用Contains()方法。所以,现在我有相当于

的东西
string s = "ABCD";
if(s.Contains("A")
{
    //do stuff
}
else if(s.Contains("E")
{
    //do different stuff
}
etc ...

我尝试过不同的方法来实现switch语句,例如

switch()
{
    case(s.Contains("A"))
    {
        //do stuff
    }
}

但我尝试的每种方式都会导致语法错误。

有没有办法在使用Contains()方法测试字符串时使用switch语句?

5 个答案:

答案 0 :(得分:3)

不,switch语句需要案例标签的常量值。所以一般来说,最好坚持使用if语句。但这与您在场景中使用switch语句的距离非常接近。

string myString = "ABC";
List<string> subStrings = new List<string>{"A", "B", "C"};
switch (subStrings.FirstOrDefault(myString.Contains))
{
    case "A":
        Console.WriteLine("Has A");
        break;
    case "B":
        Console.WriteLine("Has B");
        break;
    case "C":
        Console.WriteLine("Has C");
        break;
    default:
        Console.WriteLine("No ABC");
        break;
}

我怀疑它会比if语句更快,因为FirstOrDefault基本上做同样的事情,它打破了DRY主体,因为它需要更新列表和{{1声明。

答案 1 :(得分:1)

首先想到的是

        string s = "ABCD";

        foreach (char oneChar in s.ToCharArray())
        {
            switch (oneChar)
            {
                case 'A':
                    Console.WriteLine("Do A stuff");
                    break;
                case 'B':
                    Console.WriteLine("Do B stuff");
                    break;
                case 'C':
                    Console.WriteLine("Do C stuff");
                    break;
                case 'D':
                    Console.WriteLine("Do D stuff");
                    break;
                default:
                    break;
            }
        }

取决于你在做什么,这可能是也可能不是一种有效的方式。如果字符串中的大多数字符实际上导致分支到这些情况之一,那么这将更有效,因为您不必进行一堆字符串包含搜索。如果字符串中有很多字符没有匹配的分支(它们什么也不做),那么这可能不是一种有效的方法。

答案 2 :(得分:1)

如果你可以在你的场景中使用它,那么通常会提醒我一个使用枚举物以获得灵活性的好地方。我可能会这样做:

string input = "ABDE";
var mapping = new Dictionary<Func<string, bool>, Action<string>>()
{
    { (string i) => i.Contains("A"), (string i) => Console.WriteLine("Found input with 'A'") },
    { (string i) => i.Contains("B"), (string i) => Console.WriteLine("Found input with 'B'") },
    { (string i) => i.Contains("C"), (string i) => Console.WriteLine("Found input with 'C'") },
    { (string i) => i.Contains("D"), (string i) => Console.WriteLine("Found input with 'D'") }
};

foreach (var criteria in mapping)
{
    if (criteria.Key(input)) {
        criteria.Value(input);
        break;
    }
}

通过这种方式将测试/操作条件组合在一起,您可以使用foreach干净地运行所有规则而无需太多工作,并且添加/删除规则更容易。

答案 3 :(得分:1)

使用C#7.0中的pattern matching feature,现在可以在switch语句中使用Contains。提供比多个if else块更清晰的代码。以下代码示例显示了如何执行此操作

        var patterns = new[] { "dog", "cat", "cats and dogs", "parrot", "parrot and cat" };

        foreach (var item in patterns)
        {
            switch (item)
            {
                case var s when s.Contains("cat"):
                    Console.WriteLine($"{item} contains cat");
                    break;

                case var s when s.Contains("dog"):
                    Console.WriteLine($"{item} contains dog");
                    break;

                case var s when s.Contains("parrot"):
                    Console.WriteLine($"{item} contains parrot");
                    break;
            }
        }

请注意,它不适用于早于C#7.0的版本。

答案 4 :(得分:0)

如果您有很多这些行,有时使用字典将目标值映射到操作可以更清晰,更灵活,例如:

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApplication1
{
    public class Program
    {
        static void Main()
        {
            var dict = new Dictionary<string, Action<string>>
            {
                ["A"] = Console.WriteLine,
                ["B"] = doSomething1,
                ["C"] = doSomething2,
                ["D"] = str => Console.WriteLine("Inline: " + str)
            };

            string s = "ABCD";
            string first = dict.Keys.FirstOrDefault(t => s.Contains(t));

            if (first != null)
                dict[first](first);
            else
                ; // Default behaviour.
        }

        private static void doSomething1(string x)
        {
            Console.WriteLine("doSomething1 with " + x);
        }

        private static void doSomething2(string x)
        {
            Console.WriteLine("doSomething2 with " + x);
        }
    }
}

“更灵活”我的意思是你可以传递字典,如果你想在一个地方映射动作并在其他地方使用它。

(这使用C#6语法初始化字典。)

说了这么多,在我看来是一个不必要的复杂功能,除非你想传递字典。如果不这样做,那么只使用if / else级联可能是最好的方法。

(注意:这个答案与Mike Corcoran的相似 - 我在写作的同时也是他的,似乎。我会把它留在这里,因为它需要稍微不同的方法。)