Some optimizations have been made for Struct in. NET6. Let's take a look at the optimizations for Struct in. NET6 through some cases.
Although there was a record in the previous version, the record in the previous version is a class and a reference type, but the record struct is a value type and a structure. Its usage is as follows:
record struct Point(int X, int Y);
In. NET6, record is also supported to declare a class based record, which is the same as the original record, such as record class RecordModel(int Id, string Name) and record RecordModel(int Id, string Name)
Record struct will automatically generate Equals and GetHashCode and rewrite = = and= Operator, and you can use with to modify some properties to create a new object. If record struct declares a parameter constructor, an implicit parameterless construct is generated. The code is as follows:
var p1 = new Point(1, 2); var p2 = p with { X = 2 }; Console.WriteLine(p1); Console.WriteLine(p2); Console.WriteLine(new Point());
Running the above code, you can see that a parameterless construct is generated to initialize even if no parameterless construct is explicitly declared. The above code output is as follows:
Point { X = 1, Y = 2 } Point { X = 2, Y = 2 } Point { X = 0, Y = 0 }2, readonly struct record
We can use readonly to mark the structure or readonly struct record, but record struct cannot be modified with ref. For the structure declared with readonly struct record, if the Primary Constructor is used, the corresponding attribute will be init. For example, readonly record struct Point(int X, int Y); The declaration of the attribute is as follows:
internal readonly struct Point : IEquatable<Point> { public int X { get; init; } public int Y { get; init; } public Point(int X, int Y) { this.X = X; this.Y = Y; } }3, Parameterless Constructor
. NET6 supports user-defined parameterless construction methods. We can add initialization logic to the parameterless construction methods. The code is as follows:
Console.WriteLine(new Point1().ToString()); Console.WriteLine(default(Point1).ToString()); Console.WriteLine(Activator.CreateInstance<Point1>()); struct Point1 { public int X { get; set; } public int Y { get; set; } private int Z { get; set; } public Point1() { X = 1; Y = 2; Z = 3; } public override string ToString() { return $"__"; } }
Note the difference between default and new. Default is the empty state of the structure and will not execute parameterless construction. New will execute. The construction will also be executed when creating objects through reflection. The code output results are as follows:
1_2_3 0_0_0 1_2_3
In addition to record,. NET6 also extends the use of the with expression. Common structures and anonymous objects can also use with to modify some properties. The code is as follows:
Console.WriteLine((new Point1() with { X = 2 }).ToString()); Console.WriteLine(); var obj = new { X = 1, Y = 1 }; Console.WriteLine(JsonSerializer.Serialize(obj)); Console.WriteLine(JsonSerializer.Serialize(obj with { X = 3, Y = 3 }));
The output results are as follows:
2_2_3 {"X":1,"Y":1} {"X":3,"Y":3}
With can only operate on public members. Z in the above code is private, so it cannot be specified in the with expression.
Compared with record class, record struct has no Clone method, because struct does not need its own Clone function. Record struct does not allow to declare Clone member methods, and all records do not allow to declare Clone members.