使用自定义隐式转换快速创建失败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. ...
随机推荐
- Linux离线包管理器RPM
Linux离线包管理器RPM RPM 是RedHat Package Manager(RedHat软件包管理工具). 1.rpm常用参数介绍 查看rpm是否安装 rpm -q rpm包名 [root@ ...
- sqlserver用windows方式验证登录踩过的坑
坑位一: 之前没用过windows验证方式登录sqlserver,连接串怎么写 坑位二: 链接上了,但是启动报错 八月 19, 2020 9:33:43 上午 com.microsoft.sqlser ...
- 一篇文章带你使用Typescript封装一个Vue组件
一.搭建项目以及初始化配置 vue create ts_vue_btn 这里使用了vue CLI3自定义选择的服务,我选择了ts.stylus等工具.然后创建完项目之后,进入项目.使用快捷命令code ...
- 关于使用 koa路由与mysql模块, ctx.body获取不到值的问题
var Koa = require('koa');var Router = require('koa-router' );var bodyParser = require('koa-bodyparse ...
- SAP 实例 8 HTML from the MIME Repository
REPORT demo_html_from_mime. CLASS mime_demo DEFINITION. PUBLIC SECTION. CLASS-METHODS main. PRIVATE ...
- 为什么新的5G标准将为技术栈带来更低的 TCO
摘要 新5G标准和边缘计算对低延迟的要求,给那些试图将一堆不同组件组装成一个不会出现故障且仍具有低延迟的高成本效益应用程序公司带来了严峻的挑战.事实上,这个问题非常严重,以至于需要重新考虑架构. ...
- 关于Java中的构造方法
关于构造方法: 1.构造方法又叫构造函数/构造器. 2.构造方法语法结构中"返回值类型"不需要指定,也不能写void,如若写void,则变成普通方法. 3.构造方法有返回值,和当前 ...
- identityserver4 (ids4)中如何获取refresh_token刷新令牌token 使用offline_access作用域
ids4默认自带的api接口/api/connect/token 调用这个接口的时候,需要在body里面的 x-www-form-urlencoded模式下写 { grant_type: &q ...
- 活动报名:以「数」制「疫」,解密 Tapdata 在张家港市卫健委数字化防疫场景下的最佳实践
疫情两年有余,全国抗疫攻防战步履不停.在"动态清零"总方针的指导下,国内疫情防控工作渐趋规范化.常态化.健康码.行程卡.疫情地图.电子哨兵.核酸码.场所码--各类精准防疫手 ...
- SpringBoot快速整合通用Mapper
前言 后端业务开发,每个表都要用到单表的增删改查等通用方法,而配置了通用Mapper可以极大的方便使用Mybatis单表的增删改查操作. 通用mapper配置 1.添加maven: <depen ...