浅析 record 使用场景

Intro

之前我们有介绍过 record 基本知识,可以参考 C# 9 新特性 — 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 使用场景相关推荐

  1. 倾斜摄影超大场景的三维模型轻量化与三维展示效果的关系浅析

    倾斜摄影超大场景的三维模型轻量化与三维展示效果的关系浅析 倾斜摄影超大场景的三维模型由于数据量庞大,直接进行渲染可能会导致计算资源和时间的浪费.因此,针对倾斜摄影超大场景的三维模型区域进行轻量化处理是 ...

  2. 倾斜摄影超大场景的三维模型的顶层合并的优势浅析

    倾斜摄影超大场景的三维模型的顶层合并的优势浅析 倾斜摄影超大场景的三维模型的顶层合并具有以下优势: 1.三维可视化效果好:通过倾斜摄影技术可以获得高分辨率的地面影像,将其与三维建模相结合可以生成非常逼 ...

  3. 倾斜摄影超大场景的三维模型在网络发布应用遇到常见的问题浅析

    倾斜摄影超大场景的三维模型在网络发布应用遇到常见的问题浅析 倾斜摄影超大场景的三维模型在网络发布应用时,常见的问题包括: 1.加载速度慢.由于数据量巨大,网络发布时需要将数据文件分割成多个小文件进行加 ...

  4. 竞争专题·第4篇:五大场景下的竞争对手分析内容

    前期断断续续写过一些关于竞争分析.标杆分析.竞争策略方面的内容,有从方法本身切入的,比如华为五看三定.华为九招制胜.华为五环十四招等方法工具中,竞争分析处于什么位置,以及竞争分析的大致内容. 竞争专题 ...

  5. C# 实现一个基于值相等性比较的字典

    C# 实现一个基于值相等性比较的字典 Intro 今天在项目里遇到一个需求,大概是这样的我要比较两个 JSON 字符串是不是相等,JSON 字符串其实是一个 Dictionary<string, ...

  6. aop框架 php,xaop: 支持三种模式的AOP框架,弥补PHPer的不足,并且自带了文档的解析类库,可以一并使用,性能极好,欢迎 STAR 与 FORK。...

    Xaop PHP高性能的AOP扩展 功能特色 基于对象的文档注解AOP模式 方法注入AOP模式 属性AOP模式 系统指令及其含义 xaop.method_prefix AOP文档注解需要排除的方法前缀 ...

  7. flutter 打开后闪退_vscode 扩展 pubspec 依赖快速打开文档

    最近初步学习了下 Flutter (https://flutter.dev/). 在学习一些开源代码的过程中发现一个小小需求:pubspec.yaml 中有很多 dependencies,初学者很多都 ...

  8. java + ffmped + mencoder搭建视频处理平台

    java + ffmped + mencoder搭建视频处理平台 ffmpeg+mencoder几乎可以完成目前基于web的播客平台任何音视频处理的操作.如果还需要添加一些什么的话,那么就是视频在线录 ...

  9. 基于JWT规范实现的认证微服务

    本文由公众号EAWorld翻译发表,转载需注明出处. 作者:Marcelo Fonseca 译者:白小白 原题:Building an authentication micro-service wit ...

最新文章

  1. 常用开源协议介绍以及开源软件规范列表
  2. bootstrap栅格分5等分
  3. 手写Python中列表和字符串的反转
  4. C# 打开指定的文件夹 记住路径中 / 与 \ 的用法
  5. 开源手机自动化测试框架iQuery入门教程(一)
  6. 云笔记/笔记软件工具
  7. 马上就要到了的即时通讯
  8. 泛型类 0104 c#
  9. java中的链接之其他窗体_两个窗体之间的链接
  10. Android 系统(233)---AOSP 代码管理
  11. Loadrunner如何监控Linux系统资源
  12. 了解一点儿JavaConfig
  13. 【外传】前端开发——elementUI使用方法
  14. 模拟电路和数字电路的学习笔记(精华总结55条)
  15. 如何在php中添加音乐播放器,音乐播放器的制作实例(html5)-
  16. android 判断base64编码格式,一文带你读懂base64编码
  17. 杭电ACM 2014:青年歌手大奖赛_评委会打分
  18. 湖北智禾网店指导:新开卖家必须要了解的淘宝交易流程及交易规则。
  19. 技术部负责人的爱恨情仇
  20. wps分享为什么要登入_杭州诠网科技有限公司分享seo优化为什么要做网站地图

热门文章

  1. PHP 利用Mail_MimeDecode类提取邮件信息
  2. php OpenSSL 加解密
  3. Axure RP使用攻略--动态面板的用途(8)
  4. Ruby 学习笔记3
  5. 什么叫内部银团_什么是紫钛晶?紫钛晶是不是天然水晶?
  6. 如何将世界时钟和时区小部件添加到您的iPhone
  7. 小程序 iphone和安卓_如何阻止iPhone和iPad应用程序要求评级
  8. vue-router query,parmas,meta传参
  9. highcharts 怎么去掉鼠标悬停效果_练瑜伽减肥没效果什么原因?
  10. 如何让程序跑起来――第三章