在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的好答案可以通过用以下内容替换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;