編程隨筆(一):泛型與重載
來自專欄編程隨筆
需求:
多個讀寫文件的靜態函數,需要返回處理的結果或拋出的異常
分析:
返回一個對象,保存如下內容:
- bool Success 表示函數執行是否成功
- T Value 保存函數正常執行後返回的結果
- string Error 表示人工或系統拋出的信息
實現:
寫起來太簡單了,分分鐘鐘的事。
/// <summary> /// 已精簡的代碼 /// </summary> /// <typeparam name="T"></typeparam> class Result<T> { T Value; bool Success; string ErrorMsg; /// <summary> /// 返回錯誤信息的構造函數 /// </summary> /// <param name="error"></param> public Result(string error) { Success = false; ErrorMsg = error; } /// <summary> /// 返回正確結果的構造函數 /// </summary> /// <param name="error"></param> public Result(T value) { Success = true; Value = value; } } public static void main() { var resultOK = new Result<double>(3.1415); var resultNG = new Result<double>("Wrong PI"); }
怎樣,很簡單吧?
但是這個和標題有什麼關係呢?哪裡有問題呢?
唔~~ o(* ̄▽ ̄*)o......
等等!好像有種情況沒有考慮到!!!
如果正確返回的類型就是 string 類型怎麼辦?
public static void main() { var resultOK = new Result<string>("3.1415"); var resultNG = new Result<string>("Wrong PI"); }
這個時候 Result 類的構造函數傳入的參數類型就是一樣的了,編譯器會調哪一個函數呢?!
額......按照通常的 C++ 思維,應該會調那個最貼切的構造函數吧!
也確實是這樣的,在 T 為 string 時,編譯器會優先選擇那個 Success 永遠為 false 的構造函數,也就是這個返回的結果永遠是 NG 的。
解決方案
這......這好像也沒啥解決方案,用工廠函數避免一下就好了嘛!
/// <summary> /// 已精簡的代碼 /// </summary> /// <typeparam name="T"></typeparam> class Result<T> { T Value; bool Success; string ErrorMsg; private Result(bool _success, T _value, string _errormsg) { Success = _success; Value = _value; ErrorMsg = _errormsg; } /// <summary> /// 返回錯誤信息的工廠函數 /// </summary> /// <param name="error"></param> public static Result<T> CreateNGResult(string error) { return new Result<T>(false, default(T), error); } /// <summary> /// 返回正確結果的工廠函數 /// </summary> /// <param name="error"></param> public static Result<T> CreateOKResult(T value) { return new Result<T>(true, value, string.Empty); } } public static void main() { var resultOK = Result<string>.CreateOKResult("3.1415"); var resultNG = Result<string>.CreateNGResult("Wrong PI"); }
以上!
推薦閱讀:
※Python中的變數、對象、引用
※面向對象介紹
※【白話python連載(9.2)】 python的os模塊
※python自動化常用模塊