SoFunction
Updated on 2025-03-06

C# record usage scenario

Intro

We've introduced it beforerecord Basic knowledgerecordI will implement value-based type comparison, and I think it is useful for several recent problems. record It will be very convenient to solve it, share it

Value-based type comparison

Recently I encountered a scenario where I need to compare whether two JSON strings are equal. The string is relatively simple, just a fixed value.Dictionary, or think it's just a simple oneModel, but the attribute order of JSON strings may be different, for example, the following example:

{"Id":1, "Name":"Tom"}, {"Name":"Tom", "Id":1}, These two strings are in different orders from the string and are naturally not equal, but the values ​​of the corresponding attributes are the same. How can we compare them more conveniently? record It can be more convenient to compare, and see the code:

record Person(int Id, string Name);

[Fact]
public void RecordTest()
{
 var str1 = "{\"Id\":1, \"Name\":\"Tom\"}";
 var p1 = <Person>(str1);

 var str2 = "{\"Name\":\"Tom\",\"Id\":1}";
 var p2 = <Person>(str2);

 (p1 == p2);
 (p1, p2);
}

Deduplication based on value comparison

We have an API that has received feedback that the results returned by multiple calls are different, so I want to write a piece of code to call it a hundred times to see if there will be duplication. The general code is as follows:

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 ("");
 var result = <Result>(responseText);
 (result);
}
();

becauserecordNot only will it be rewriteEqualsThe method will also be rewrittenGetHashCodeMethod, so you can useHashSetorDictionaryGo and do it

Object cloning

recordProvidedwithExpressions can be used to easily clone a new object, so you can consider using it when you need to clone it.record, and all prototype modes can be consideredrecordTo achieve

Previously, I implemented a simple logging framework, which has a log object, defined as follows:

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)
 {
   = new Dictionary<string, object>();
  foreach (var property in Properties)
  {
  [] = ;
  }
 }
 return newEvent;
 }
}

We can useMemberwiseCloneMake a simplified

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)
 {
   = new Dictionary<string, object>();
  foreach (var property in Properties)
  {
  [] = ;
  }
 }
 return newEvent;
 }
}

UsedrecordAfter that,withThe expression returns a strong type object, and no longer needs to do a forced type conversion by yourself. The above method is a relatively tricky method, and it is used.MemberwiseCloneDo copying. If you write the code yourself to copy it one by one, it will be more cumbersome.recordIt's very simple after that, but we need to pay attention to it.withExpressions are also just shallow copying. If they contain complex reference types, they need to be used with caution.

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)
 {
   = new Dictionary<string, object>();
  foreach (var property in Properties)
  {
  [] = ;
  }
 }
 return newEvent;
 }
}

More

recordIn many scenarios, our code can be simplified, making the code cleaner and more concise. Don’t forget to use it in suitable scenarios~

Microsoft's reverse proxy project YARP is also usedrecordTo simplify the original code DeepClone For functions, please refer to PR:/microsoft/reverse-proxy/pull/662

The above is the detailed content of the use scenarios of c# record. For more information about the use scenarios of c# record, please pay attention to my other related articles!