大家都知道,代碼中出現過多的if…else嵌套語句時很難讀,所以常用switch…case語句進行代替,代碼的可讀性就好了很多。

舉個簡單的例子:

public void DoSomeThing(string str)
    {
      if (str == "A") {
        DoSomethingForA(str);
      }
      else if (str == "B") {
        DoSomethingForB(str);
      }
      else if (str == "C") {
        DoSomethingForC(str);
      }
    }

我們一眼就看出,這段代碼可以使用switch語句進行重構,重構後的代碼如下:

public void DoSomeThing(string str)
    {
      switch (str) {
        case "A":
          DoSomethingForA(str);
          break;
        case "B":
          DoSomethingForB(str);
          break;
        case "C":
          DoSomethingForC(str);
          break;
        default:
          break;
      }
    }

 

這樣看下去,代碼確實清晰了很多.這種重構方法我們很多人都會這麼做,而且效果還不錯.上面的例子中代碼行還很少,實際當中有可能會出現很多的case語句, 即使我們這樣重構,在閲讀的時候還是需要拉很長的滾動條才可以看到需要找的case語句對應的代碼.所以,針對這種情況,我們還可以用更簡潔的方法進行重構. 實現起來也挺簡單的,即:建立全局的字典類型的變量,保存不同的case語句條件以及對應的方法,這樣,在需要調用的時候直接查找到該方法,invoke即可,其實也是用了委託來實現.看以下代碼:

private static Dictionary<string, Action<string>> dict = new Dictionary<string, Action<string>>();
      
    public BuildDictionary()
    {
      dict.Add("A", DoSomethingForA);
      dict.Add("B", DoSomethingForB);
      dict.Add("C", DoSomethingForC);
    }

上面是聲明變量及填充字典,做好這部分的工作之後,調用起來就方便多了,同樣的DoSomeThing方法,代碼就少了很多

public void DoSomeThing(string str)
    {
      if (dict.ContainsKey(str)) {
            Action<string> action = dict[str];
            action.Invoke(str);
      }
    }

重構之後,是不是簡潔了很多,即使再多的case語句,我們也只需要在BuildDictionary方法中把它添加進去就可以了。

那麼,是不是所有的switch…case語句都可以這樣重構呢,以這樣的實現方式來看,需要case條件對應的方法參數類型相同,這樣才容易構造出字典來保存。

如果方法還要返回值,那我們就不能用Action,需要用Func表達式來保存,因為它可以帶有返回值。