Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do I have to define every single operator?

Suppose I have a struct with just one field:

public struct Angle
{
    public static readonly double RadiansPerDegree = Math.PI / 180;

    private readonly double _degrees;

    public Angle(double degrees)
    {
        _degrees = degrees;
    }

    public double Degrees
    {
        get { return _degrees; }
    }

    public double Radians
    {
        get { return _degrees * RadiansPerDegree; }
    }

    public static Angle FromDegrees(double value)
    {
        return new Angle(value);
    }

    public static Angle FromRadians(double value)
    {
        return new Angle(value / RadiansPerDegree);
    }
}

This works great, until I want to do stuff like this:

var alpha = Angle.FromDegrees(90);
var beta = Angle.FromDegrees(100);
var inequality = alpha > beta;
var sum = alpha + beta;
var negation = -alpha;
//etc.

So, I implemented IEquatable<in T> and IComparable<in T>, but that still didn't enable any operators (not even ==, <, >=, etc.).

So, I started providing operator overloads.

For example:

public static Angle operator +(Angle a, Angle b)
{
    return new Angle(a._degrees + b._degrees);
}

public static Angle operator -(Angle a)
{
    return new Angle(-a._degrees);
}

public static bool operator >(Angle a, Angle b)
{
    return a._degrees > b._degrees;
}

This worked, however, when I looked at all the operators I could conceivably overload (+, -, !, ~, ++, --, true, false, +, -, *, /, %, &, |, ^, <<, >>, ==, !=, <, >, <=, >=), I started to feel like there must be a better way. After all, the struct only contains one field, and that field is a value type.

Is there some way to enable all the operators of double in one shot? Or do I really have to type out every operator I could possibly want to support by hand?

(Even if I had two or three fields, I'd still like to be able to add the operators in one batch...)

like image 307
devuxer Avatar asked Feb 02 '23 09:02

devuxer


1 Answers

The point of overloading operators is to define how to add to manipulate objects of a custom type using those operators, so if your second field was a string array, how would you expect the ++ operator to be implemented automatically? There is no sensible answer, especially since we don't know the context of the object or it's usage, so the answer is yes, you do have to overload the operators yourself.

For the record, if you really do only need one field, and it's just a double, then don't use a struct in the first place unless you need to overload the operators to perform some other action than they do by default — it's a clear case of over-engineering!

like image 199
Matt Lacey Avatar answered Feb 06 '23 11:02

Matt Lacey