在Switch语句中使用.StartsWith?

我正在处理一个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"; } 

你正在切换一个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"; } 

结果将是相同的。

案例标签必须是字符串,因为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"; } 

其中^表示行的起点| 意思是。

只是为了好玩,这是另一个避免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" }, }; 

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

 private static string GetSomeStringOrOther(string subArea) { // Create a set of pattern matching functions... Func matchEquals = (a, b) => a.Equals(b); Func matchStarts = (a, b) => a.StartsWith(b); // Create a rule set... Tuple>[] cases = new [] { new Tuple>("4100", "ABC", matchEquals), new Tuple>("4101", "ABC", matchEquals), new Tuple>("4102", "ABC", matchEquals), new Tuple>("4200", "ABC", matchEquals), new Tuple>("600A", "XWZ", matchEquals), new Tuple>("3*", "123", matchStarts), new Tuple>("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"; } 

好处

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

缺点

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

改进

  • Tuple>替换为表示Rule的语义对象

使用LINQ, @ 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;