重构大型if-else代码

本文关键字:代码 if-else 大型 重构 | 更新日期: 2023-09-27 17:57:29

如果其他代码,我有这个很长的代码

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

等等。。。。。

我怎么能把它改写成更好看的东西。尝试在这里学习一些新的东西,我已经进入了.net 2.0。谢谢你的帮助。

重构大型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];

这应该是非常简单的

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#中,您可以将字符串与==进行比较。

CCD_ 2做与CCD_ 3相同的事情。

首先,DRY原则-不要重复自己。将errorNumbers.Substring(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];

范围:

如果您需要支持范围,那么基本上必须使用if/else块。还有其他选项,但如果您的代码中只有这么多这样类型的if/else块,那么它们往往过于复杂。

您应该初始化一个字典,其中包含errorCode和errorMessage 之间的引用

Dictionary<int, string> errorsCache = new Dictionary<int, string>()
{
  {1101,"AutoRepickAfterPickError"},
  {2121,"AutoRepickAfterPickError"},
  {1401,"AutoRepickAfterCAlignError"},
  ...
}

您可以定义GetErrorDescription方法

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

首先,将errorNumbers.Substring(0,4)存储在长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";
        }
}

Select Case怎么样?:D

errorNumber = errorNumbers.Substring(0,4)
Select Case errorNumber 
   Case 1101,2121
      retStr = "AutoRepickAfterPickError";
   Case 1301,2321
      retStr = "AutoRepickAfterLAlignError";
   ...
End Select