使用自定義隱式轉換快速創建失敗Result

  系統要求方法都返回 Result 結果,通常我們會如此定義一個 Result

 1     public class Result<T>
 2     {
 3         public virtual int Code { get; set; }
 4 
 5         public virtual T Data { get; set; }
 6 
 7         public virtual string Message { get; set; }
 8     }
 9 
10     public class Result : Result<object>
11     {
12         // 快速創建成功結果
13         public static Result<T> Success<T>(T data)
14         {
15             return new Result<T>() { Data = data };
16         }
17 
18         // 快速創建失敗結果
19         public static Result<T> Fail<T>(int code, string message)
20         {
21             return new Result<T>() { Code = code, Message = message };
22         }
23     }

  得益於C#強大的類型推斷,我們可以非常簡單的返回成功或失敗結果

 1     public Result<User> GetUser(int userId)
 2     {
 3         User user = null; // Read from database
 4         if (user == null)
 5         {
 6             return Result.Fail<User>(400, "用戶不存在");  // 需要手動指明 User,有點煩
 7         }
 8         else
 9         {
10             return Result.Success(user);
11         }
12     }

  成功的時候,Success() 方法可以自動推斷出Data爲 User 類;

  但是失敗的時候,必須手動的指明Data爲 User 類,雖然僅僅多敲了幾個字母,但我還是想簡化,因爲失敗時,Data根本不需要賦值,也不在乎Data 的類型。

  C# 可以使用 Implicit 自定義隱式轉換,可以將 Result 自動隱式轉換轉換爲 Result<T>,考慮到我們只需要在失敗的時候才轉換,所以我定義了一個  FailResult

 1     public class FailResult : Result
 2     {
 3     }
 4 
 5     public class Result : Result<object>
 6     {
 7         // 新增加的方法
 8         public static FailResult Fail(int code, string message)
 9         {
10             return new FailResult() { Code = code, Message = message };
11         }
12     }

  這樣的話,不論時成功還是失敗,我們都不需要指定Data 的類型了

 1     public Result<User> GetUser(int userId)
 2     {
 3         User user = null; // Read from database
 4         if (user == null)
 5         {
 6             return Result.Fail(400, "用戶不存在"); // 不用指明 <User> 了
 7         }
 8         else
 9         {
10             return Result.Success(user);
11         }
12     }

  心細的朋友會發現,這種 Result.Fail 其實是先 new 一個 FailResult,然後編譯器再 new 一個 Result<T>, 事實上多創建了一個無用的實例,但我覺得對於CLR而言這種開銷可以忽略不記。

  

  下面是完整的代碼:

 1 using System;
 2 
 3 namespace ConsoleApp1
 4 {
 5     class Program
 6     {
 7         static void Main(string[] args)
 8         {
 9             Console.WriteLine("Hello World!");
10         }
11 
12         public Result<User> GetUser(int userId)
13         {
14             User user = null; // Read from database
15             if (user == null)
16             {
17                 return Result.Fail(400, "用戶不存在"); // 不用指明 <User> 了
18                 //return Result.Fail<User>(400, "用戶不存在");
19             }
20             else
21             {
22                 return Result.Success(user);
23             }
24         }
25     }
26 
27     public class Result<T>
28     {
29         public virtual int Code { get; set; }
30 
31         public virtual T Data { get; set; }
32 
33         public virtual string Message { get; set; }
34 
35 
36         public static implicit operator Result<T>(FailResult failResult)
37         {
38             return new Result<T>() { Code = failResult.Code, Message = failResult.Message };
39         }
40     }
41 
42     public class Result : Result<object>
43     {
44         public static Result<T> Success<T>(T data)
45         {
46             return new Result<T>() { Data = data };
47         }
48 
49         public static Result<T> Fail<T>(int code, string message)
50         {
51             return new Result<T>() { Code = code, Message = message };
52         }
53 
54         public static FailResult Fail(int code, string message)
55         {
56             return new FailResult() { Code = code, Message = message };
57         }
58     }
59 
60     public class FailResult : Result 
61     { 
62     }
63 
64     public class User
65     { 
66     }
67 }
View Code

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章