用委托封裝C#的Try...Catch

開發軟件過程中,為了防止程序崩潰出錯都會用 try ... catch 包裹住會產生異常的代碼。隨著項目越來越大,try ... catch 語句到處都是,令人眼花的花括號,丑陋無比的縮進讓人崩潰。

IO 操作通常最容易引發異常,文件讀寫網絡訪問數據庫操作這些,比如讀取當前目錄的文本:

string text = System.IO.File.ReadAllText("demo.txt");
Console.WriteLine(text);
IO 異常

這時就需要在外層用 try ... catch 將這兩行代碼包括起來,并提示錯誤:

try
{
    string text = System.IO.File.ReadAllText("demo.txt");
    Console.WriteLine(text);
}
catch (System.IO.IOException ex)
{
    Console.WriteLine(ex.Message);
}

為了簡化上面的代碼結構,在這里我們可以設計一個靜態方法,將需要執行的代碼作為參數,在 try ... catch 里執行它。如何將要執行的代碼作為參數傳給另外一個方法呢,我們可以用 Action<T> 和 Fun<T> 委托,他們一個是無返回參數,一個是有返回參數。

public static void Try(Action act, Action<Exception> errorCallback = null)
{
    try
    {
        act();
    }
    catch (Exception ex)
    {
        errorCallback?.Invoke(ex);
    }
}

這個 Try 方法接受兩個委托作為參數,第一個是要執行的代碼,第二個是出現了異常也好返回一個 Exception 類型給調用方,并且它是一個可為 null 類型的參數,也就是可選參數。

把這個方法放到一個靜態類 TryCatch 里,在調用的類使用 using 語句使用這個靜態類,沒錯,C# 6 就是這么叼。

using static TryCatch;

改造后的語句:

string text = "";
Try(() =>
{
    text = System.IO.File.ReadAllText("demo.txt");
}, error =>
{
     WriteLine(error.Message);
});

這里就很厲害了,代碼竟然沒有變短反而變長了和更難理解了。

繼續改造,使用 Func<T>:

public static T Try<T>(Func<T> func, Func<Exception, T> errorCallback = null)
{
    try
    {
        return func();
    }
    catch (Exception ex)
    {
        if (errorCallback != null)
        {
            return errorCallback(ex);
        }
        return default(T);
    }
}

再繼續改造剛才的代碼:

string text = Try(()=> { return System.IO.File.ReadAllText("demo.txt"); });
WriteLine(text);

震驚!某知名函數竟然不報錯,原因竟然是這:

return default(T);

很好理解,就是返回默認值了。

可以在那兩個靜態類里加入 logger,這樣每一個 try ... catch 報錯都可以記錄下來,同理還可以對實現了 IDispose 接口的類封裝,省略 using 代碼塊。

本文在依然在 天兵公園 公眾號,博客簡書 同步發布,轉載前務必聯系

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容