2021-01-30

浅析 record 使用场景

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









原文转载:http://www.shaoqun.com/a/521163.html

跨境电商:https://www.ikjzd.com/

reverb:https://www.ikjzd.com/w/1273

母婴团购网:https://www.ikjzd.com/w/716


record浅析record使用场景Intro之前我们有介绍过record基本知识,record会实现基于值的类型比较,最近遇到的几个问题觉得用record来解决会非常方便,分享一下基于值的类型比较最近有遇到一个场景,需要比较两个JSON字符串是否相等,字符串比较简单,就是一个固定值的Dictionary,或者认为它就是一个简单的Model,但是JSON字符串的的属性顺序可能不同,比如说下面的这个
parser:parser
五洲会海购:五洲会海购
Noon平台怎么样? Noon平台入驻要求、流程揭秘!:Noon平台怎么样? Noon平台入驻要求、流程揭秘!
【干货】亚马逊的这些工具一定要会用!:【干货】亚马逊的这些工具一定要会用!
B2C五步攻略法,轻松拿下海外电商市场!:B2C五步攻略法,轻松拿下海外电商市场!

No comments:

Post a Comment