C# 在Switch语句中使用.StartsWith?

C# 在Switch语句中使用.StartsWith?,c#,asp.net,.net,C#,Asp.net,.net,我正在处理一个Switch语句,有两个条件需要查看值是否以特定值开始。Switch语句是这样的。错误显示“无法将类型bool转换为字符串” 有人知道我是否可以在交换机中使用StartsWith,或者我需要使用if…Else语句吗 switch(subArea) { case "4100": case "4101": case "4102": ca

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

有人知道我是否可以在交换机中使用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#>=7,请首先查看答案


您正在切换一个
字符串
,而
子区域。StartsWith()
返回一个
布尔值
,这就是您无法执行此操作的原因。我建议你这样做:

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";
}
结果将是相同的。

编辑:如果您使用的是C#>=7,请先查看答案


您正在切换一个
字符串
,而
子区域。StartsWith()
返回一个
布尔值
,这就是您无法执行此操作的原因。我建议你这样做:

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

结果将是相同的。

大小写标签必须是字符串,因为开关表达式是字符串;但是,
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";
}
此外,星号(*)可能是错误的,除非您希望
子区域包含它
StartWith
不接受通配符

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

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

其中,
^
表示行的开头,
|
表示或。

由于开关表达式是字符串,因此大小写标签必须是字符串;但是,
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";
}
此外,星号(*)可能是错误的,除非您希望
子区域包含它
StartWith
不接受通配符

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

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

其中,
^
表示行的开始,
|
表示或。

只是为了好玩,这里有另一个避免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
匹配,例如:


为了好玩,这里有另一个避免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
匹配,例如:


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";
}
私有静态字符串GetSomeStringOrOther(字符串子区域)
{
//创建一组模式匹配函数。。。
Func matchEquals=(a,b)=>a.Equals(b);
Func matchStarts=(a,b)=>a.StartsWith(b);
//创建一个规则集。。。
Tuple[]cases=new[]
{
新元组(“4100”、“ABC”、matchEquals),
新元组(“4101”、“ABC”、matchEquals),
新元组(“4102”,“ABC”,matchEquals),
新元组(“4200”、“ABC”、matchEquals),
新元组(“600A”、“XWZ”、matchEquals),
新元组(“3*”,“123”,匹配开始),
新元组(“03*”,“123”,匹配开始),
};
//找一根火柴。。。
foreach(案例中的var matchCase)
{
if(匹配案例项目3(子区域,匹配案例项目1))
{
//如果匹配,则返回。。。
返回matchCase.Item2;
}
}
//否则返回默认值。。。
返回“ABCXYZ123”;
}
优势

  • 如果您需要一个新规则,可以很容易地添加到规则集中
  • 如果您需要一个新的模式匹配功能,再次,易于添加
  • 如果规则发生更改,则不需要大量返工
缺点

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

  • 元组
    替换为表示
    规则的语义对象

    • 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";
      }
      
      私有静态字符串GetSomeStringOrOther(字符串子区域)
      {
      //创建一组模式匹配函数。。。
      Func matchEquals=(a,b)=>a.Equals(b);
      Func matchStarts=(a,b)=>a.StartsWith(b);
      //创建一个规则集。。。
      Tuple[]cases=new[]
      {
      新元组(“4100”、“ABC”、matchEquals),
      新元组(“4101”、“ABC”、matchEquals),
      新元组(“4102”,“ABC”,matchEquals),
      新元组(“4200”、“ABC”、matchEquals),
      新元组(“600A”、“XWZ”、matchEquals),
      新元组(“3*”,“123”,匹配开始),
      新元组(“03*”,“123”,匹配开始),
      };
      //找一根火柴。。。
      foreach(案例中的var matchCase)
      {
      if(匹配案例项目3(子区域,匹配案例项目1))
      {
      //如果匹配,则返回。。。
      返回matchCase.Item2;
      }
      }
      //否则返回默认值。。。
      返回“ABCXYZ123”;
      }
      
      优势

      • 如果您需要一个新规则,可以很容易地添加到规则集中
      • 如果您需要一个新的模式匹配功能,再次,易于添加
      • 如果规则发生更改,则不需要大量返工
      缺点

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

      • 元组
        替换为表示
        规则的语义对象
      使用LINQ,可以通过将
      foreach
      return
      语句替换为以下语句来“简化”一点:

      // 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;
      
      使用LINQ,可以通过将
      foreach
      return
      语句替换为以下语句来稍微“简化”一点:

      // 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;
      
      多亏了,您现在可以执行以下操作:

      开关(分区)
      {
      //跳过