我正在处理一个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";
}
其中^
的意思是起始线,|
的意思是。
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
使用LINQ,the nice answer by @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;
只是为了好玩,这是另一个避免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" },
};
感谢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";
}