c# record的使用場景
Intro
之前我們有介紹過 record 基本知識,record 會實現(xiàn)基于值的類型比較,最近遇到的幾個問題覺得用 record 來解決會非常方便,分享一下
基于值的類型比較
最近有遇到一個場景,需要比較兩個 JSON 字符串是否相等,字符串比較簡單,就是一個固定值的 Dictionary,或者認(rèn)為它就是一個簡單的 Model,但是 JSON 字符串的的屬性順序可能不同,比如說下面的這個示例:
{"Id":1, "Name":"Tom"}, {"Name":"Tom", "Id":1},這兩個字符串從字符串上來說順序不同,自然不相等,但是對應(yīng)的屬性的值是相同的,怎么比較方便的進(jìn)行比較呢,使用 record 可以比較方便進(jìn)行比較,來看代碼:
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 有收到反饋說,調(diào)用多次返回的結(jié)果不同,于是我就想寫一段代碼調(diào)用個一百次看是否會有重復(fù),大致代碼如下:
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 來實現(xiàn)去重
對象克隆
record 提供了 with 表達(dá)式來方便的克隆一個新的對象,所以在需要克隆的時候可以考慮使用 record,另外所有原型模式的地方都可以考慮使用 record 來實現(xiàn)
之前我實現(xiàn)了一個簡單的日志框架,有一個日志對象,定義如下:
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 表達(dá)式返回的是強類型的對象,不再需要自己做強制類型轉(zhuǎn)換了,上面的做法還是比較取巧的辦法,使用了 MemberwiseClone 去做復(fù)制,如果自己寫代碼一個一個復(fù)制,將會更加繁瑣,使用 record 之后就很簡單了,只是我們需要注意一下,with 表達(dá)式也只是淺復(fù)制,如果內(nèi)部包含復(fù)雜引用類型,需要小心使用
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的使用場景的詳細(xì)內(nèi)容,更多關(guān)于c# record的使用場景的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Js中的substring,substr與C#中的Substring比較
本篇文章主要是對Js中的substring,substr與C#中的Substring進(jìn)行了比較。需要的朋友可以過來參考下,希望對大家有所幫助2014-01-01
Unity UGUI的RectMask2D遮罩組件的介紹使用
這篇文章主要為大家介紹了Unity UGUI的RectMask2D遮罩組件的介紹使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07
C#實現(xiàn)讀取被進(jìn)程占用的文件實現(xiàn)方法
這篇文章主要介紹了C#實現(xiàn)讀取被進(jìn)程占用的文件實現(xiàn)方法,涉及C#進(jìn)程操作及文件讀取的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-08-08
C#實現(xiàn)將商品金額小寫轉(zhuǎn)換成大寫的方法
這篇文章主要介紹了C#實現(xiàn)將商品金額小寫轉(zhuǎn)換成大寫的方法,涉及C#數(shù)組與字符串的相關(guān)操作技巧,具有一定參考借鑒價值,需要的朋友可以參考下2016-08-08

