使用自定义隐式转换快速创建失败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, "用户不存在");
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 }
使用自定义隐式转换快速创建失败Result的更多相关文章
- C#中的类型转换-自定义隐式转换和显式转换
目录 前言 基础知识 示例代码 实际应用 问题 答案 报错 用户定义的转换必须是转换成封闭类型,或者从封闭类型转换 参考 其他 应用和设计 读音 参考 前言 有时我们会遇到这么一种情况:在json数据 ...
- scala自定义隐式转换
Scala自定义隐式转换 一.编写隐式转换类 /** * Author Mr. Guo * Create 2019/4/20 - 17:40 */ object StringImprovments { ...
- F#中的自定义隐式转换
我们知道隐式变换在可控情况下会使代码变得简洁.熟悉C#的都知道C#中可以自定义隐式变换,例如 public class A { private int data; public static impl ...
- ahjesus自定义隐式转换和显示转换
implicit 关键字用于声明隐式的用户定义类型转换运算符. 如果可以确保转换过程不会造成数据丢失,则可使用该关键字在用户定义类型和其他类型之间进行隐式转换. 参考戳此 explicit ...
- 大数据技术之_16_Scala学习_06_面向对象编程-高级+隐式转换和隐式值
第八章 面向对象编程-高级8.1 静态属性和静态方法8.1.1 静态属性-提出问题8.1.2 基本介绍8.1.3 伴生对象的快速入门8.1.4 伴生对象的小结8.1.5 最佳实践-使用伴生对象解决小孩 ...
- 9. Scala隐式转换和隐式值
9.1 隐式转换 9.1.1 提出问题 先看一个案例演示,引出隐式转换的实际需要=>指定某些数据类型的相互转化 object boke_demo01 { def main(args: Array ...
- C#中的隐式转换
你是否考虑过这个问题:为什么不同类型之间的变量可以赋值,而不需要强制转换类型?如: int i = 1; long l = i; object obj = 1; Exception exception ...
- 无废话Android之smartimageview使用、android多线程下载、显式意图激活另外一个activity,检查网络是否可用定位到网络的位置、隐式意图激活另外一个activity、隐式意图的配置,自定义隐式意图、在不同activity之间数据传递(5)
1.smartimageview使用 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android&q ...
- 深入理解Scala的隐式转换系统
摘要: 通过隐式转换,程序员可以在编写Scala程序时故意漏掉一些信息,让编译器去尝试在编译期间自动推导出这些信息来,这种特性可以极大的减少代码量,忽略那些冗长,过于细节的代码. 使用方式: 1. ...
随机推荐
- 5. Docker compose
把上图添加路径后,改成下图: 上图之后需要source /etc/profile #此命令重新加载环境变量文件. 在任意目录下输入docker-compose测试下,docker-compose是否安 ...
- rpm构建流程学习总结
rpm构建流程 学习链接: b站马哥: https://www.bilibili.com/video/BV1ai4y1N7gp RedHat: https://access.redhat.com/do ...
- 六、LVM和从磁盘配额
一.LVM概述 Logical Volume Manager,逻辑卷管理 优点:能够保证在现有数据不变的情况下,动态调整磁盘容量,从而提高磁盘管理的灵活性 /boot分区用于存放引导文件,不能基于LV ...
- 一文详解JackSon配置信息
背景 1.1 问题 Spring Boot 在处理对象的序列化和反序列化时,默认使用框架自带的JackSon配置.使用框架默认的,通常会面临如下问题: Date返回日期格式(建议不使用Date,但老项 ...
- 又拍云 Redis 的改进之路
作为推出国内首创可编程 CDN 服务的专业云服务提供商,又拍云利用 CDN 边缘网络规模和性能,允许客户自定义编写规则来满足常用业务场景.而为了保证这些源数据,如边缘重定向.请求限速.自定义错误页面. ...
- NC15975 小C的记事本
NC15975 小C的记事本 题目 题目描述 小C最近学会了java小程序的开发,他很开心,于是想做一个简单的记事本程序练练手. 他希望他的记事本包含以下功能: 1.append(str),向记事本插 ...
- NC14662 小咪买东西
NC14662 小咪买东西 题目 题目描述 小咪是一个土豪手办狂魔,这次他去了一家店,发现了好多好多( \(n\) 个)手办,但他是一个很怪的人,每次只想买 \(k\) 个手办,而且他要让他花的每一分 ...
- 降低PDF质量
如果PDF尺寸过大,则需要降低其质量以缩小尺寸.在Linux下一条命令即可实现,而且效果不错: gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFS ...
- SpringMVC底层——请求参数处理流程描述
在DispatcherServlet.java的doDispatch方法中,springmvc通过handlermapping里面找哪个handler能处理请求,handler封装了目标方法的信息, ...
- 如何在Excel/WPS表格中批量查询快递信息?
如何在Excel/WPS表格中批量查询快递信息? 干电商的小伙伴们还在为如何批量查询快递物流信息发愁吗?别着急,这篇文章或许能够帮助到您. 首先给大家看一下查询的具体成果: 第一步:安装Excel网络 ...