3

使用自定义隐式转换快速创建失败Result - zhouandke

 2 years ago
source link: https://www.cnblogs.com/zhouandke/p/16621462.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

使用自定义隐式转换快速创建失败Result - zhouandke - 博客园

posts - 26,  comments - 49,  views -

61339

  系统要求方法都返回 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而言这种开销可以忽略不记。

  下面是完整的代码:

ContractedBlock.gifExpandedBlockStart.gif

View Code


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK