服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C# - c# record的使用场景

c# record的使用场景

2022-10-31 11:32WeihanLi C#

这篇文章主要介绍了c# record的使用场景,帮助大家更好的理解和学习使用c#的新特性,感兴趣的朋友可以了解下

Intro

之前我们有介绍过 record 基本知识record 会实现基于值的类型比较,最近遇到的几个问题觉得用 record 来解决会非常方便,分享一下

基于值的类型比较

最近有遇到一个场景,需要比较两个 JSON 字符串是否相等,字符串比较简单,就是一个固定值的 Dictionary,或者认为它就是一个简单的 Model,但是 JSON 字符串的的属性顺序可能不同,比如说下面的这个示例:

{"Id":1, "Name":"Tom"}, {"Name":"Tom", "Id":1},这两个字符串从字符串上来说顺序不同,自然不相等,但是对应的属性的值是相同的,怎么比较方便的进行比较呢,使用 record 可以比较方便进行比较,来看代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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 有收到反馈说,调用多次返回的结果不同,于是我就想写一段代码调用个一百次看是否会有重复,大致代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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 来实现

之前我实现了一个简单的日志框架,有一个日志对象,定义如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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 做一个简化

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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 表达式也只是浅复制,如果内部包含复杂引用类型,需要小心使用

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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

以上就是c# record的使用场景的详细内容,更多关于c# record的使用场景的资料请关注服务器之家其它相关文章!

原文链接:https://www.cnblogs.com/weihanli/p/14347769.html

延伸 · 阅读

精彩推荐
  • C#总结C#删除字符串数组中空字符串的几种方法

    总结C#删除字符串数组中空字符串的几种方法

    C#中要如何才能删除一个字符串数组中的空字符串呢?下面的文章会介绍多种方式来实现清除数组中的空字符串,以及在.net中将字符串数组中字符串为空的...

    C#教程网11442021-12-03
  • C#C#中如何利用正则表达式判断字符

    C#中如何利用正则表达式判断字符

    这篇文章主要介绍了C#中利用正则表达式判断字符的实例代码,非常不错,具有参考借鉴价值,需要的朋友可以参考下...

    C#教程网4402021-12-15
  • C#C# 如何获取出错的错误所在行数信息

    C# 如何获取出错的错误所在行数信息

    本文主要介绍 C# 中获取错误所在行的方法,在开发过程中或是用户在使用过程中,出错的话方便我们快速定位到错误的位置,以便我们处理。...

    yourber4882021-11-19
  • C#关于C#中ajax跨域访问问题

    关于C#中ajax跨域访问问题

    最近做项目,需要跨域请求访问数据问题。下面通过本文给大家分享C#中ajax跨域访问代码详解,需要的朋友可以参考下...

    CDL_Darren7472022-01-05
  • C#C# PC版微信消息监听自动回复的实现方法

    C# PC版微信消息监听自动回复的实现方法

    这篇文章主要介绍了C# PC版微信消息监听自动回复的实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要...

    小赫赫4442022-09-08
  • C#C# Winform选项卡集成窗体详解

    C# Winform选项卡集成窗体详解

    这篇文章主要为大家详细介绍了C# Winform选项卡集成窗体详解的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    绛河6252022-01-24
  • C#关于Unity C# Mathf.Abs()取绝对值性能测试详解

    关于Unity C# Mathf.Abs()取绝对值性能测试详解

    这篇文章主要给大家介绍了关于Unity C# Mathf.Abs()取绝对值性能测试的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Unity C#具有一定的参...

    冰封百度4332022-07-20
  • C#C#调用OpenCV开发简易版美图工具【推荐】

    C#调用OpenCV开发简易版美图工具【推荐】

    本文主要介绍在WPF项目中使用OpenCVSharp3-AnyCPU开源类库处理图片,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友参考下吧...

    kiba5189172022-08-07