在Switch语句中使用.StartsWith?

问题描述 投票:11回答:6

我正在处理一个Switch语句,并且有两个条件我需要查看值是否以特定值开头。 Switch语句是这样的。错误说“不能将bool类型转换为字符串”。

任何人都知道我是否可以在Switch中使用StartsWith或者我是否需要使用If ... Else语句?

switch(subArea)
            {
                case "4100":
                case "4101":
                case "4102":
                case "4200":
                    return "ABC";
                case "600A":
                    return "XWZ";
                case subArea.StartsWith("3*"):
                case subArea.StartsWith("03*"):
                    return "123";
                default:
                    return "ABCXYZ123";
            }
c# asp.net .net
6个回答
12
投票

你正在切换StringsubArea.StartsWith()返回Boolean,这就是为什么你不能这样做。我建议你这样做:

if (subArea.StartsWith("3*") || subArea.StartsWith("03*"))
    return "123";

switch(subArea)
{
    case "4100":
    case "4101":
    case "4102":
    case "4200":
        return "ABC";
    case "600A":
        return "XWZ";
    default:
        return "ABCXYZ123";
}

结果将是相同的。


5
投票

案例标签必须是字符串,因为switch表达式是一个字符串;但是,StartsWith返回一个布尔值。我建议在default部分处理这些特殊情况。

switch(subArea)
{
    case "4100":
    case "4101":
    case "4102":
    case "4200":
        return "ABC";
    case "600A":
        return "XWZ";
    default:
        if (subArea.StartsWith("3") || subArea.StartsWith("03")) {
            return "123";
        }
        return "ABCXYZ123";
}

星(*)也可能是错的,除非你想让subArea包含它。 StartWith不接受通配符。

或者你可以使用正则表达式:

if (Regex.IsMatch(subArea, "^3|^03")) { // or "^(3|03)"
    return "123";
}

其中^的意思是起始线,|的意思是。


4
投票

Joe有点打败我,但这是另一种非切换方式,它基本上实现了一个带有规则集的模式匹配算法。

private static string GetSomeStringOrOther(string subArea)
{
    // Create a set of pattern matching functions...
    Func<string, string, bool> matchEquals = (a, b) => a.Equals(b);
    Func<string, string, bool> matchStarts = (a, b) => a.StartsWith(b);

    // Create a rule set...
    Tuple<string, string, Func<string, string, bool>>[] cases = new []
    {
        new Tuple<string, string, Func<string, string, bool>>("4100", "ABC", matchEquals),
        new Tuple<string, string, Func<string, string, bool>>("4101", "ABC", matchEquals),
        new Tuple<string, string, Func<string, string, bool>>("4102", "ABC", matchEquals),
        new Tuple<string, string, Func<string, string, bool>>("4200", "ABC", matchEquals),
        new Tuple<string, string, Func<string, string, bool>>("600A", "XWZ", matchEquals),
        new Tuple<string, string, Func<string, string, bool>>("3*", "123", matchStarts),
        new Tuple<string, string, Func<string, string, bool>>("03*", "123", matchStarts),
    };

    // Look for a match...
    foreach(var matchCase in cases)
    {
        if(matchCase.Item3(subArea, matchCase.Item1))
        {
            // Return if it matches...
            return matchCase.Item2;
        }
    }

    // Otherwise return the default...
    return "ABCXYZ123";
}

好处

  • 如果您需要新规则,则可以轻松添加到规则集中。
  • 如果你需要一个新的模式匹配功能,再次,易于添加。
  • 如果规则发生变化,则无需进行大量返工。

缺点

  • 新手/初学者甚至一些中级开发人员可能都不知道发生了什么。

改进

  • 用代表Tuple<string, string, Func<string, string, bool>>的语义对象替换Rule

3
投票

使用LINQ,the nice answer by @seriesOne可以通过用以下代码替换foreachreturn语句来“简化”:

// using System.Linq;

// Look for a match...
var result = cases
    .Where(c => c.Item3(subArea, c.Item1))
    .FirstOrDefault();

// Return the match or the default.
return result == null ? "ABCXYZ123" : result.Item2;

2
投票

只是为了好玩,这是另一个避免switch语句的解决方案。

var map = new[] {
    new { Value = "4100", StartsWith = false, Result="ABC" },
    new { Value = "4101", StartsWith = false, Result="ABC" },
    new { Value = "4102", StartsWith = false, Result="ABC" },
    new { Value = "4200", StartsWith = false, Result="ABC" },
    new { Value = "600A", StartsWith = false, Result="XWZ" },
    new { Value = "3*", StartsWith = true, Result="123" },
    new { Value = "03*", StartsWith = true, Result="123" },
};

var subarea = ... whatever ...;

var result = map.Where(e =>
        {
            if (e.StartsWith)
            {
                return subarea.StartsWith(e.Value);
            }
            else
            {
                return subarea == e.Value;
            }
        }
    )
    .Select(e => e.Result)
    .FirstOrDefault() ?? "ABCXZ123";

数组map中的顺序决定了优先级,因此,例如,你可以在“3 * 11”上进行完全匹配,以及在“3 *”上进行StartsWith匹配,例如:

var map = new[] {
    new { Value = "3*11", StartsWith = false, Result="ABC" },
    new { Value = "4100", StartsWith = false, Result="ABC" },
    new { Value = "4101", StartsWith = false, Result="ABC" },
    new { Value = "4102", StartsWith = false, Result="ABC" },
    new { Value = "4200", StartsWith = false, Result="ABC" },
    new { Value = "600A", StartsWith = false, Result="XWZ" },
    new { Value = "3*", StartsWith = true, Result="123" },
    new { Value = "03*", StartsWith = true, Result="123" },
};

2
投票

感谢when clause,您现在可以:

            switch (subArea)
            {
                // Skipping regular cases with string literals
                case string dummy
                    when subArea.StartsWith("3*") ||
                         subArea.StartsWith("03*"):
                    return "123";
                default:
                    return "ABCXYZ123";
            }
© www.soinside.com 2019 - 2024. All rights reserved.