C# 重构大型if-else代码
我有很长的if-else代码C# 重构大型if-else代码,c#,.net,refactoring,C#,.net,Refactoring,我有很长的if-else代码 if (errorNumbers.Length == 6) { if (errorNumbers.Substring(0,4).Equals("1101") || errorNumbers.Substring(0,4).Equals("2121")) { retStr = "AutoRepickAfterPickError"; } else if (errorNumbe
if (errorNumbers.Length == 6)
{
if (errorNumbers.Substring(0,4).Equals("1101") || errorNumbers.Substring(0,4).Equals("2121"))
{
retStr = "AutoRepickAfterPickError";
}
else if (errorNumbers.Substring(0, 4).Equals("1301") || errorNumbers.Substring(0, 4).Equals("2321"))
{
retStr = "AutoRepickAfterLAlignError";
}
else if (errorNumbers.Substring(0, 4).Equals("1401") || errorNumbers.Substring(0, 4).Equals("2221"))
{
retStr = "AutoRepickAfterCAlignError";
}
else if (errorNumbers.Substring(0, 4).Equals("1501") || errorNumbers.Substring(0, 4).Equals("2041"))
{
retStr = "AutoRepicksAfterManualRecovery";
}
等等
我怎么能把它改写成更好的东西。
尝试在这里学习一些新的东西,我现在在.NET2.0中。
谢谢你的帮助。这应该很简单
if (errorNumbers.Length == 6)
{
string errNo = errorNumbers.Substring(0, 4);
switch (errNo)
{
case "1101":
case "2121":
retStr = "AutoRepickAfterPickError";
break;
case "1301":
case "2321":
retStr = "AutoRepickAfterLAlignError";
break;
case "1401":
case "2221":
retStr = "AutoRepickAfterCAlignError";
break;
case "1501":
case "2041":
retStr = "AutoRepicksAfterManualRecovery";
break;
}
}
还请注意,与Java不同,在C语言中,您可以将字符串与=
进行比较
“123”==“456”
的作用与“123”的作用相同。等于(“456”)
首先,在长if/else之前将errorNumber.Substring(0,4)
存储在局部变量中
然后,您可以使用映射/字典将整个if/else从预期的错误号消除到相应的返回字符串。我将错误代码映射到字典中,如下所示:
string errorCode = errorNumbers.Substring(0, 4);
Dictionary<string, string> map = new Dictionary<string,string>();
map.Add("1501", "AutoRepicksAfterManualRecovery");
map.Add("2041", "AutoRepicksAfterManualRecovery");
map.Add("1401", "AutoRepickAfterCAlignError");
map.Add("2221", "AutoRepickAfterCAlignError");
map.Add("1301", "AutoRepickAfterPickError");
map.Add("2121", "AutoRepickAfterPickError");
// etc
if(!map.ContainsKey(errorCode))
throw new Exception("Invalid error code");
return map[errorCode];
stringerrorcode=errorNumbers.Substring(0,4);
字典映射=新字典();
地图添加(“1501”,“自动恢复”);
地图添加(“2041”,“自动恢复”);
地图添加(“1401”,“自动校准错误”);
地图添加(“2221”,“自动校准错误”);
map.Add(“1301”,“自动检索错误”);
添加(“2121”,“自动检索错误”);
//等
如果(!map.ContainsKey(错误代码))
抛出新异常(“无效错误代码”);
返回映射[错误代码];
选择案例怎么样D
errorNumber = errorNumbers.Substring(0,4)
Select Case errorNumber
Case 1101,2121
retStr = "AutoRepickAfterPickError";
Case 1301,2321
retStr = "AutoRepickAfterLAlignError";
...
End Select
首先。将errorNumbers.子字符串(0,4)
的结果分配给局部变量:
string subNumbers = errorNumbers.SubString(0, 4);
if (subNumbers == "1401") // ...
支持特定价值案例(非范围):
可以将switch语句与字符串一起使用:
switch(subNumbers)
{
case "1401":
case "2221":
retStr = "AutoRepickAfterCAlignError";
break;
case "1501":
case "2041":
retStr = "AutoRepicksAfterManualRecovery";
break;
// etc
}
switch语句的另一种替代方法是创建字典:
var selections = new Dictionary<string, string>()
{
{ "1401", "AutoRepickAfterCAlignError" },
{ "2221", "AutoRepickAfterCAlignError" },
{ "1501", "AutoRepicksAfterManualRecovery" },
{ "2041", "AutoRepicksAfterManualRecovery" },
// etc
};
if (selections.ContainsKey(subNumbers))
retStr = selections[subNumbers];
var selections=newdictionary()
{
{“1401”,“自动校准错误”},
{“2221”,“自动校准错误”},
{“1501”,“自动恢复”},
{“2041”,“自动恢复”},
//等
};
if(选择项.容器(子编号))
retStr=选择[子编号];
范围:
如果需要支持范围,则基本上必须使用If
/else
块。还有其他选项,但如果代码中只有这么多的if
/else
块,则这些选项往往过于复杂。您可以尝试以下方法:
if (errorNumbers.Length == 6)
{
//Makes it easier to change error codes, as theyre all in one place
string[] AutoRepickAfterPickError = { "1101", "2121"};
string[] AutoRepickAfterLAlignError = { "1301", "2321"};
string[] AutoRepickAfterCAlignError = { "1401", "2221"};
string[] AutoRepicksAfterManualRecovery = { "1501", "2041"};
string subString = errorNumbers.Substring(0,4);
if (AutoRepickAfterPickError.Contains(subString));
{
retStr = "AutoRepickAfterPickError";
}
else if (AutoRepickAfterLAlignError.Contains(subString))
{
retStr = "AutoRepickAfterLAlignError";
}
else if (AutoRepickAfterCAlignError.Contains(subString))
{
retStr = "AutoRepickAfterCAlignError";
}
else if (AutoRepicksAfterManualRecovery.Contains(subString))
{
retStr = "AutoRepicksAfterManualRecovery";
}
}
您应该使用errorCode和errorMessage之间的引用来初始化字典
Dictionary<int, string> errorsCache = new Dictionary<int, string>()
{
{1101,"AutoRepickAfterPickError"},
{2121,"AutoRepickAfterPickError"},
{1401,"AutoRepickAfterCAlignError"},
...
}
首先,干的原则-不要重复你自己()。将
errorNumbers.Substring(0,4)
的结果分配给一个局部变量。您“可以”使用策略模式,但在大多数情况下,这是一个完全的过度使用,有时很难维护。这是一个C#而不是VB.Net问题。最好是删除答案大IfElse/SwitchCase保留在此处接受的,它实际上更冗长,可能更快。我只是不喜欢switch,因为它添加了额外的代码。它没有什么“错误”,但是字典,最好是这样的静态字典,比switch语句更容易维护。是的,我也会使用它,这在我的示例中不是很明显,因此接受的答案可能更详细一些。dictionary和switch的性能可能非常相似,因为带字符串的switch可能会在后台使用哈希表。但是,此示例中的两个查找而不是一个查找(例如TryGetValue)会使查找速度稍慢。它还应该是一个缓存的静态字典,如@Yaur所说。如果性能对这段代码很重要……事实上,我利用ContainsKey使示例更直观。然后,对于列表中的6-12个条目,问题是这是否有什么区别,但坚持练习总是好的:)
public string GetErrorDescription(string errorNumbers)
{
string retStr;
if (errorNumbers.Length == 6)
{
int errorCode;
if(int.TryParse(errorNumbers.Substring(0,4), out errorCode))
{
errorsCache.TryGetValue(errorCode, out retStr);
}
}
return retString;
// or you can return empty string instead of null
return retString ?? "";
}