To understand record struct, first look at the following Employee struct:
struct Employee
{
public string Name { get; set; }
public int Age { get; set; }
}
class Program
{
static void Main(string[] args)
{
Employee e1 = new Employee();
Employee e2 = new Employee();
e1.Name = "Swami"; e1.Age = 23;
e2.Name = "Swami"; e2.Age = 23;
Console.WriteLine(e1.Equals(e2));
Console.WriteLine(e1 == e2); // Error
}
}
Note: You cannot use equality(==) operator to check equality of two structs because in C# the == operator is not automatically defined for custom structs. To convert the above struct into record struct, simply use record before struct keyword:
record struct Employee
{
public string Name { get; set; }
public int Age { get; set; }
}
class Program
{
static void Main(string[] args)
{
Employee e1 = new Employee();
Employee e2 = new Employee();
e1.Name = "Swami"; e1.Age = 23;
e2.Name = "Swami"; e2.Age = 23;
Console.WriteLine(e1.Equals(e2));
Console.WriteLine(e1 == e2); // True
}
}
Note: You can use equality(==) operator to check equality of two record struct objects because record structs automatically generate value-based equality for equality operator.
Observation1. You cannot use equality operator to check equality of two structs but you can use equality operator to check equality of two record structs.
Observation2. A 'struct' or 'record struct' with field initializers must include an explicitly declared constructor otherwise compiler will throw error. The following code will throw error:
struct Employee
{
public string Name { get; set; } = string.Empty; // field initializer
public int Age { get; set; }
}
To correct the error, use an explicitly declared constructor.
struct Employee
{
public string Name { get; set; } = string.Empty;
public int Age { get; set; }
public Employee(string Name, int Age)
{
this.Name = Name;
this.Age = Age;
}
}
Note. A class with field initializer does not require explicitly declared constructor. The following code compiles successfully:
class Employee
{
public string Name { get; set; } = string.Empty; // field initializer
public int Age { get; set; }
}
Observation3. The record struct can use primary constructor but struct cannot. Even a class cannot use primary constructor.
record struct Employee(string Name, int Age){}//OK
struct Employee(string Name, int Age){}//Error
Observation4. The record struct with primary constructor has implicit parameterless constructor. The same is true with struct. Every struct has an implicit parameterless constructor.
record struct Employee(string Name, int Age)
{
}
class Program
{
static void Main(string[] args)
{
Employee e1 = new Employee();
Employee e2 = new Employee();
e1.Name = "Swami"; e1.Age = 23;
e2.Name = "Swami"; e2.Age = 23;
Console.WriteLine(e1.Equals(e2));
Employee e3 = new Employee("Ajeet", 23);
Console.WriteLine(e3.Name + " " + e3.Age);
}
}Observation5. A struct cannot have explicit parameterless constructor but a class can have. Note: since C#10, this rule is restricted. Now struct can behave like class in this regard.
struct Employee
{
public int Name { get; set; }
public int Age { get; set; }
Employee(string Name, int Age)
{
}
public Employee()
{
// Error before C#10: struct cannot have explicit
// parameterless constructor
// but class can have
}
}
Observation6. ToString() method returns type name w.r.t. struct but record struct returns also object properties.
Example with struct
struct Employee
{
public string Name { get; set; } = string.Empty;
public int Age { get; set; }
public Employee(string Name, int Age)
{
this.Name = Name;
this.Age = Age;
}
}
class Program
{
static void Main(string[] args)
{
Employee e1 = new Employee("Ajeet", 23);
Console.WriteLine(e1.ToString()); // Employee
}
}
Example with record struct
record struct Employee
{
public string Name { get; set; } = string.Empty;
public int Age { get; set; }
public Employee(string Name, int Age)
{
this.Name = Name;
this.Age = Age;
}
}
class Program
{
static void Main(string[] args)
{
Employee e1 = new Employee("Ajeet", 23);
Console.WriteLine(e1.ToString()); // Employee { Name=Ajeet Age=23 }
}
}
Observation7. record struct supports supports non-destructive mutation using with keyword but struct does not:
record struct Employee(string Name, int Age);
class Program
{
static void Main(string[] args)
{
var e1 = new Employee("Swami", 23);
var e2 = e1 with { Age = 30 }; // normal struct will throw error
Console.WriteLine(e1); // Employee { Name = Swami, Age = 23 }
Console.WriteLine(e2); // Employee { Name = Swami, Age = 30 }
}
}
Comparison between struct and record struct:
- Both are value type.
- Both provide value-based equality by default but:
- Equality operator provides value-based equality with record structs but throws error with structs.
- Equals() method provide value-based equality for both struct and record struct.
- Primary constructor is allowed with record struct but not with struct.
- ToString() method returns type name w.r.t. struct but record struct returns also object properties.
- They can be immutable or mutable depending on init or set property.
- The record struct supports supports non-destructive mutation using with keyword but struct does not.
No comments:
Post a Comment