浅析 record 使用场景
浅析 record 使用场景
Intro
之前我们有介绍过 record 基本知识,record 会实现基于值的类型比较,最近遇到的几个问题觉得用 record 来解决会非常方便,分享一下
基于值的类型比较
最近有遇到一个场景,需要比较两个 JSON 字符串是否相等,字符串比较简单,就是一个固定值的 Dictionary,或者认为它就是一个简单的 Model,但是 JSON 字符串的的属性顺序可能不同,比如说下面的这个示例:
{"Id":1, "Name":"Tom"}, {"Name":"Tom", "Id":1},这两个字符串从字符串上来说顺序不同,自然不相等,但是对应的属性的值是相同的,怎么比较方便的进行比较呢,使用 record 可以比较方便进行比较,来看代码:
record Person(int Id, string Name);
[Fact]
public void RecordTest()
{
var str1 = "{\"Id\":1, \"Name\":\"Tom\"}";
var p1 = JsonConvert.DeserializeObject<Person>(str1);
var str2 = "{\"Name\":\"Tom\",\"Id\":1}";
var p2 = JsonConvert.DeserializeObject<Person>(str2);
Assert.True(p1 == p2);
Assert.Equal(p1, p2);
}
基于值比较的去重
我们有一个 API 有收到反馈说,调用多次返回的结果不同,于是我就想写一段代码调用个一百次看是否会有重复,大致代码如下:
public record Result
{
public string Data { get; set;}
public int Code { get; set; }
}
var i = 100;
var results = new HashSet<Result>();
using var httpClient = new HttpClient();
while(i-- > 0)
{
var responseText = await httpClient.GetStringAsync("");
var result = JsonConvert.DeserializeObject<Result>(responseText);
results.Add(result);
}
Console.WriteLine(results.Count);
因为 record 不仅会重写 Equals 方法还会重写 GetHashCode 方法,所以可以使用 HashSet 或者 Dictionary 来实现去重
对象克隆
record 提供了 with 表达式来方便的克隆一个新的对象,所以在需要克隆的时候可以考虑使用 record,另外所有原型模式的地方都可以考虑使用 record 来实现
之前我实现了一个简单的日志框架,有一个日志对象,定义如下:
public class LogHelperLoggingEvent : ICloneable
{
public string CategoryName { get; set; }
public DateTimeOffset DateTime { get; set; }
public string MessageTemplate { get; set; }
public string Message { get; set; }
public LogHelperLogLevel LogLevel { get; set; }
public Dictionary<string, object> Properties { get; set; }
public LogHelperLoggingEvent Copy()
{
var newEvent = new LogHelperLoggingEvent()
{
CategoryName = CategoryName,
DateTime = DateTime,
MessageTemplate = MessageTemplate,
Message = Message,
LogLevel = LogLevel
};
if (Properties != null)
{
newEvent.Properties = new Dictionary<string, object>();
foreach (var property in Properties)
{
newEvent.Properties[property.Key] = property.Value;
}
}
return newEvent;
}
}
我们可以使用 MemberwiseClone 做一个简化
public class LogHelperLoggingEvent : ICloneable
{
public string CategoryName { get; set; }
public DateTimeOffset DateTime { get; set; }
public string MessageTemplate { get; set; }
public string Message { get; set; }
public LogHelperLogLevel LogLevel { get; set; }
public Dictionary<string, object> Properties { get; set; }
public LogHelperLoggingEvent Copy()
{
var newEvent = (LogHelperLoggingEvent)MemberwiseClone();
if (Properties != null)
{
newEvent.Properties = new Dictionary<string, object>();
foreach (var property in Properties)
{
newEvent.Properties[property.Key] = property.Value;
}
}
return newEvent;
}
}
使用了 record 之后如下,with 表达式返回的是强类型的对象,不再需要自己做强制类型转换了,上面的做法还是比较取巧的办法,使用了 MemberwiseClone 去做复制,如果自己写代码一个一个复制,将会更加繁琐,使用 record 之后就很简单了,只是我们需要注意一下,with 表达式也只是浅复制,如果内部包含复杂引用类型,需要小心使用
public record LogHelperLoggingEvent
{
public string CategoryName { get; set; }
public DateTimeOffset DateTime { get; set; }
public string MessageTemplate { get; set; }
public string Message { get; set; }
public LogHelperLogLevel LogLevel { get; set; }
public Dictionary<string, object> Properties { get; set; }
public LogHelperLoggingEvent Copy()
{
var newEvent = this with{ };
if (Properties != null)
{
newEvent.Properties = new Dictionary<string, object>();
foreach (var property in Properties)
{
newEvent.Properties[property.Key] = property.Value;
}
}
return newEvent;
}
}
More
record 在很多场景下能够简化我们的代码,使得代码更加干净简洁,在合适的场景下不要忘记使用哦~
微软的反向代理项目 YARP 也使用了 record 来简化原来代码中 DeepClone 的功能,可以参考 PR:https://github.com/microsoft/reverse-proxy/pull/662
浅析 record 使用场景的更多相关文章
- InnoDB的锁机制浅析(五)—死锁场景(Insert死锁)
可能的死锁场景 文章总共分为五个部分: InnoDB的锁机制浅析(一)-基本概念/兼容矩阵 InnoDB的锁机制浅析(二)-探索InnoDB中的锁(Record锁/Gap锁/Next-key锁/插入意 ...
- InnoDB的锁机制浅析(二)—探索InnoDB中的锁(Record锁/Gap锁/Next-key锁/插入意向锁)
Record锁/Gap锁/Next-key锁/插入意向锁 文章总共分为五个部分: InnoDB的锁机制浅析(一)-基本概念/兼容矩阵 InnoDB的锁机制浅析(二)-探索InnoDB中的锁(Recor ...
- InnoDB的锁机制浅析(四)—不同SQL的加锁状况
不同SQL的加锁状况 文章总共分为五个部分: InnoDB的锁机制浅析(一)-基本概念/兼容矩阵 InnoDB的锁机制浅析(二)-探索InnoDB中的锁(Record锁/Gap锁/Next-key锁/ ...
- InnoDB的锁机制浅析(三)—幻读
文章总共分为五个部分: InnoDB的锁机制浅析(一)-基本概念/兼容矩阵 InnoDB的锁机制浅析(二)-探索InnoDB中的锁(Record锁/Gap锁/Next-key锁/插入意向锁) Inno ...
- InnoDB的锁机制浅析(一)—基本概念/兼容矩阵
InnoDB锁的基本概念 文章总共分为五个部分: InnoDB的锁机制浅析(一)-基本概念/兼容矩阵 InnoDB的锁机制浅析(二)-探索InnoDB中的锁(Record锁/Gap锁/Next-key ...
- InnoDB的锁机制浅析(All in One)
目录 InnoDB的锁机制浅析 1. 前言 2. 锁基本概念 2.1 共享锁和排它锁 2.2 意向锁-Intention Locks 2.3 锁的兼容性 3. InnoDB中的锁 3.1 准备工作 3 ...
- NET 2.0(C#)调用ffmpeg处理视频的方法
另外:ffmpeg的net封装库 http://www.intuitive.sk/fflib/ NET 2.0 调用FFMPEG,并异步读取输出信息的代码...public void ConvertV ...
- C# 实现一个基于值相等性比较的字典
C# 实现一个基于值相等性比较的字典 Intro 今天在项目里遇到一个需求,大概是这样的我要比较两个 JSON 字符串是不是相等,JSON 字符串其实是一个 Dictionary<string, ...
- 浅析点对点(End-to-End)的场景文字识别(图片文字)
一.背景 随着智能手机的广泛普及和移动互联网的迅速发展,通过手机等移动终端的摄像头获取.检索和分享资讯已经逐步成为一种生活方式.基于摄像头的 (Camera-based)的应用更加强调对拍摄场景的理解 ...
随机推荐
- 修改oracle监听占用8080端口号的问题
前期: 先确认Oracle已经安装并正常运行 输入lsnrctl start 启动 Oracle 输入lsnrctl status 查看Oracle运行状态 可以看到第二个PORT = 8081 是我 ...
- 记 CentOS 服务器上安装 neo4j 图数据库及本地访问
下载 去官网下载压缩包放到服务器上.地址为neo4j 下载中心,我这里选择的是 Neo4j 3.5.25 (tar).具体如何做呢?我这里使用的是土方法,即先压缩包下载到本地电脑(win 10系统), ...
- ES6中class的使用+继承
一.Class 介绍+基本语法(1).介绍通过class关键字,可以定义类.基本上,ES6 的class可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的class写法只是让对象原型的 ...
- IdentityServer4 之Client Credentials走起来
前言 API裸奔是绝对不允许滴,之前专门针对这块分享了jwt的解决方案(WebApi接口裸奔有风险):那如果是微服务,又怎么解决呢?每一个服务都加认证授权也可以解决问题,只是显得认证授权这块冗余,重复 ...
- Hive日期函数总结(转学习使用)
一.时间戳函数 1.获取当前时区的UNIX时间戳:select unix_timestamp(); 2.将指定时间转为UNIX时间戳: select unix_timestamp('2012-03-0 ...
- netcore.ydal可能是东半球最好ORM框架
typora-copy-images-to: static ydal 项目框架介绍 可能是东半球最好netcore ORM框架,目前暂时支持mysql.mssql,其核心设计目标是开发迅速.学习简单. ...
- PHP将数据集转换成树状结构
/** * 把返回的数据集转换成Tree * @param array $list 要转换的数据集 * @param string $pid parent标记字段 * @param string $l ...
- 【C++】《C++ Primer 》第十九章
第十九章 特殊工具与技术 一.控制内存分配 1. 重载new和delete new表达式的工作机理: string *sp = new string("a value"); //分 ...
- 搭乘“AI大数据”快车,肌肤管家,助力美业数字化发展
经过疫情的发酵,加速推动各行各业进入数据时代的步伐.美业,一个通过自身技术.产品让用户变美的行业,在AI大数据的加持下表现尤为突出. 对于美妆护肤企业来说,一边是进入存量市场,一边是疫后的复苏期,一边 ...
- Js中函数式编程的理解
函数式编程的理解 函数式编程是一种编程范式,可以理解为是利用函数把运算过程封装起来,通过组合各种函数来计算结果.函数式编程与命令式编程最大的不同其实在于,函数式编程关心数据的映射,命令式编程关心解决问 ...