2016-01-22 254 views
6

我正在使用Switch语句以及两个需要查看值是否以特定值开始的条件。 Switch语句的确如此。错误说“不能隐藏类型布尔到字符串”。在Switch语句中使用.StartsWith?

任何人都知道我是否可以在交换机中使用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"; 
      } 
+2

您需要使用if/else。 – adv12

+2

我想你仍然可以使用开关的所有其他值,并把默认情况下的StartsWith代码... – adv12

回答

7

您切换String,并subArea.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"; 
} 

结果将是相同的。

+0

这工作!谢谢。 – Caverman

+0

我更喜欢这个解决方案,因为它不会导致嵌套的逻辑。 – Aphelion

+0

“结果将是相同的” - 如果开关盒中没有任何值以“3 *”或“03 *”开头。 – Joe

3

由于switch表达式是一个字符串,因此case标签必须是字符串;然而,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"; 
} 

其中^意味着线的开始和|意味着

+0

感谢您的建议。看到不同的编码方式以获得相同的结果总是很好的。我不会考虑使用正则表达式。顺便说一句:在我的情况下,*实际上是数据的一部分,并没有被用作通配符。 – Caverman

+0

如果你使用正则表达式,不要忘记逃离星星:'\ *'。 –

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”的精确匹配,以及一个StartsWith匹配的“3 *”如:

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

乔那种打我给它,但这里的做这件事的另一个非开关方式,基本上实现了规则集模式匹配算法。

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

优势

  • 如果你需要一个新的规则,可以很容易地添加到规则集。
  • 如果您需要新的模式匹配功能,再次轻松添加。
  • 如果规则更改,则不需要大量返工。

缺点

  • 新手/初学者,甚至一些中间开发商可能没有一个线索是怎么回事。

改进

  • 与表示一个Rule
+0

非常好。我在[我的回答](https://stackoverflow.com/a/48014215/1497596)中提出了一个适度的变化,这可能会吸引那些对使用LINQ感兴趣的人。 – DavidRR

2

随着LINQ,the nice answer by @seriesOne可以是 “简化” 位通过用替换foreachreturn语句的语义对象替换Tuple<string, string, Func<string, string, bool>>

// 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; 
+1

一个很好的改进。 +1 – series0ne