A source generator of readonly struct.
- Declare the structure with partial and add the properties with the init accessor.
- Add the
ReadonlyStructGenerator.ReadonlyStructAttribute
to the struct.
[ReadonlyStructGenerator.ReadonlyStruct]
public partial struct Point
{
public int X { get; init; }
public int Y { get; init; }
}
After the build, the following code will be generated.
- Struct declaration with the readonly keyword.
- Definition of a primary constructor.
- Implement the
IEquatable<T>
interface. - Override
object.Equals()
,object.GetHashCode()
andobject.ToString()
. - Define operator overloading (
==
,!=
).
#nullable enable
using System;
namespace SampleConsoleApp
{
readonly partial struct Point : IEquatable<Point>
{
public Point(int x,int y) => (X,Y) = (x,y);
public bool Equals(Point other) => (X,Y) == (other.X,other.Y);
public override bool Equals(object? obj) => (obj is Point other) && Equals(other);
public override int GetHashCode() => HashCode.Combine(X,Y);
public static bool operator ==(Point left, Point right) => left.Equals(right);
public static bool operator !=(Point left, Point right) => !(left == right);
public override string ToString() => $"{nameof(Point)}({X},{Y})";
}
}
- Properties that do not have an init accessor are not subject to initialization in the constructor or to equivalence comparisons.
- If you write a constructor, it will not be generated by the SourceGenerator.
[ReadonlyStructGenerator.ReadonlyStruct]
public partial struct Vector3
{
public float X { get; init; }
public float Y { get; init; }
public float Z { get; init; }
public float Norm { get; }
public Vector3(float x, float y, float z)
{
(X, Y, Z) = (x, y, z);
Norm = (float)Math.Sqrt(X * X + Y * Y + Z * Z);
}
}
#nullable enable
using System;
namespace SampleConsoleApp
{
readonly partial struct Vector3 : IEquatable<Vector3>
{
public bool Equals(Vector3 other) => (X,Y,Z) == (other.X,other.Y,other.Z);
public override bool Equals(object? obj) => (obj is Vector3 other) && Equals(other);
public override int GetHashCode() => HashCode.Combine(X,Y,Z);
public static bool operator ==(Vector3 left, Vector3 right) => left.Equals(right);
public static bool operator !=(Vector3 left, Vector3 right) => !(left == right);
public override string ToString() => $"{nameof(Vector3)}({X},{Y},{Z})";
}
}