浅析 record 使用场景
2021-01-30 00:31
761 查看
浅析 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 { g 56c et; 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 { 56c 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
相关文章推荐
- 浅析Javascript 中的 this 的七种使用场景
- 深入浅析Vue中mixin和extend的区别和使用场景
- 浅析 Javascript 中的 this 的七种使用场景
- Swift 使用Extension 场景 浅析
- 浅析HTML5 Web Workers使用场景与作用
- 浅析Javascript 中的 this 的七种使用场景
- Redis 的 5 个常见使用场景
- 使用 Fantasy Skybox FREE 构建游戏场景
- 消息队列使用场景及各个消息队列工具对比
- php的call_user_func_array()使用场景
- Systemd 定时器:三种使用场景 | Linux 中国
- kafka入门:简介、使用场景、设计原理、主要配置及集群搭建(转)
- Python yield 使用浅析
- 消息队列使用场景
- html5 worker的使用场景
- C#进度条的使用及开发浅析
- adb shell screenrecord命令行使用说明
- Associative机制使用场景
- java架构之路-(分布式zookeeper)zookeeper真实使用场景
- 李克华 云计算高级群: 292870151 195907286 交流:Hadoop、NoSQL、分布式、lucene、solr、nutch kafka入门:简介、使用场景、设计原理、主要配置及集群搭