登录/注册
小开开
2649
占位
2
占位
0
浏览量
占位
粉丝
占位
关注
使用自定义隐式转换快速创建失败Result
小开开
2022-09-23 09:48:22 2022-09-23
14
0

系统要求方法都返回 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,考虑到我们只需要在失败的时候才转换,所以我定义了一个  FailResult

1     public class FailResult : Result
2 {
3 }
4
5 public class Result<T>
6 {
7 // 新增加的隐式转换
8 public static implicit operator Result<T>(FailResult failResult)
9 {
10 return new Result<T>() { Code = failResult.Code, Message = failResult.Message };
11 }
12 }
13
14 public class Result : Result<object>
15 {
16 // 新增加的方法
17 public static FailResult Fail(int code, string message)
18 {
19 return new FailResult() { Code = code, Message = message };
20 }
21 }

这样的话,不论时成功还是失败,我们都不需要指定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, 事实上多创建了一个无用的实例,但我觉得对于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

 

暂无评论