Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the correct way to implement operator ++ for value-types?

I'm working on a custom implementation of a Number struct, with very different ways of storing and manipulating numeric values.

The struct is fully immutable - all fields are implemented as readonly

I'm trying to implement the ++ and -- operators, and I've run into a little confusion:
How do you perform the assignment?
Or does the platform handle this automatically, and I just need to return n + 1?

public struct Number
{
    // ...
    // ... readonly fields and properties ...
    // ... other implementations ...
    // ...

    // Empty placeholder + operator, since the actual method of addition is not important.
    public static Number operator +(Number n, int value)
    {
        // Perform addition and return sum
        // The Number struct is immutable, so this technically returns a new Number value.
    }

    // ERROR here: "ref and out are not valid in this context"
    public static Number operator ++(ref Number n)
    {
        // ref seems to be required,
        // otherwise this assignment doesn't affect the original variable?
        n = n + 1;
        return n;
    }
}

EDIT: I think this is not a duplicate of other questions about increment and decrement operators, since this involves value-types which behave differently than classes in this context. I understand similar rules apply regarding ++ and --, but I believe the context of this question is different enough, and nuanced enough, to stand on its own.

like image 700
Giffyguy Avatar asked Dec 24 '22 11:12

Giffyguy


1 Answers

The struct is fully immutable - all fields are implemented as readonly

Good!

I'm trying to implement the ++ and -- operators, and I've run into a little confusion: How do you perform the assignment?

You don't. Remember what the ++ operator does. Whether it is prefix or postfix it:

  • fetches the original value of the operand
  • computes the value of the successor
  • stores the successor
  • produces either the original value or the successor

The only part of that process that the C# compiler does not know how to do for your type is "compute the successor", so that's what your overridden ++ operator should do. Just return the successor; let the compiler deal with figuring out how to make the assignment.

Or does the platform handle this automatically, and I just need to return n + 1?

Yes, do that.

like image 153
Eric Lippert Avatar answered Feb 20 '23 04:02

Eric Lippert