Skip to content

A Source Generator package that generates the >, >=, <, <= operators for a partial type (class, struct or record) which implements IComparable<T>

License

Notifications You must be signed in to change notification settings

sonnemaf/ReflectionIT.ComparisonOperatorsGenerator

Repository files navigation

ReflectionIT.ComparisonOperatorsGenerator

A Source Generator package that generates the >, >=, <, <= operators for a partial type (class, struct or record) which implements IComparable<T>.

Generating these additional operators is as simple as adding the ComparisonOperators attribute to your type. Make sure this type is partial and implements System.IComparable<T>

NuGet packages

Package Version
ReflectionIT.ComparisonOperatorsGenerator NuGet

Example

Add the NuGet package and write the following code:

using ReflectionIT.ComparisonOperatorsGenerator.Attributes;

[ComparisonOperators]
partial class Point : IComparable<Point> {

    public double X { get; }
    public double Y { get; }

    public Point(double x, double y) {
        this.X = x;
        this.Y = y;
    }

    public void Swap() => new Point(this.Y, this.X);

    public double Dist => Math.Sqrt((X * X) + (Y * Y));

    public override string ToString() => $"({X},{Y})";

    public int CompareTo(Point? other) {
        return Comparer<double?>.Default.Compare(this.Dist, other?.Dist);
    }
}

This will generate the following partial class with the 4 comparison operators.

partial class Point : System.Numerics.IComparisonOperators<Point,Point,bool> 
{
    public static bool operator <(Point left, Point right) => left.CompareTo(right) < 0;
        
    public static bool operator <=(Point left, Point right) => left.CompareTo(right) <= 0;
        
    public static bool operator >(Point left, Point right) => left.CompareTo(right) > 0;
        
    public static bool operator >=(Point left, Point right) => left.CompareTo(right) >= 0;       
}

Implement IComparisonOperators<TSelf,TOther,TResult> interface

You can automatically implement the IComparisonOperators<TSelf,TOther,TResult> interface using the ImplementIComparisonOperatorsInterface property of the ComparisonOperators attribute.

using ReflectionIT.ComparisonOperatorsGenerator.Attributes;

[ComparisonOperators(ImplementIComparisonOperatorsInterface = true)]
readonly partial record struct Time : IComparable<Time> {

    public readonly int TotalMinutes; 

    public int Hours => TotalMinutes / 60;
    public int Minutes => TotalMinutes % 60;
    public Time(int totalMinutes) {
        ArgumentOutOfRangeException.ThrowIfNegative(totalMinutes);
        TotalMinutes = totalMinutes;
    }

    public Time(int hours, int minutes) : this(hours * 60 + minutes) {
    }

    public override string ToString() => $"{this.Hours}:{this.Minutes:00}";

    public int CompareTo(Time other) => this.TotalMinutes.CompareTo(other.TotalMinutes);
}

This will generate the following partial record struct with the 4 comparison operators and the IComparisonOperators<TSelf,TOther,TResult> interface implementation

partial record struct Time : global::System.Numerics.IComparisonOperators<Time,Time,bool> 
{
    public static bool operator <(Time left, Time right) => left.CompareTo(right) < 0;
        
    public static bool operator <=(Time left, Time right) => left.CompareTo(right) <= 0;
        
    public static bool operator >(Time left, Time right) => left.CompareTo(right) > 0;
        
    public static bool operator >=(Time left, Time right) => left.CompareTo(right) >= 0;
        
}

About

A Source Generator package that generates the >, >=, <, <= operators for a partial type (class, struct or record) which implements IComparable<T>

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages