DEV Community

Cover image for New User Defined Increment and decrement in C# 14
Lou Creemers
Lou Creemers

Posted on

New User Defined Increment and decrement in C# 14

Hi lovely readers,

C# 14 just arrived with .NET 10, and it brings a fun little feature that makes custom types feel even more like built in ones. You can now decide what happens when someone writes myValue++ or myValue-- on your type.

This was possible before, but only with static methods that returned a new instance. C# 14 adds a new way to do it. You can now write instance operators that update the object directly. It is simple, it is clean, and it can help performance too.

In this post, we are going to take a friendly look at this feature and how you can try it out. Keep in mind that you need to have .NET 1- installed in order to test this out.

What this feature gives you

If you have ever created a numeric style type, you probably have used ++ to increment the number by one, or -- to decrement the number by one. Now you get to decide what these postfixes do, creating more freedom.

C# 14 still supports the classic static operator, but it also lets you write an instance version to change it for specific classes or structs like this:

public void operator ++()
{
    // Update this
}
Enter fullscreen mode Exit fullscreen mode

and the same idea works for --.

A simple example

Imagine you have a small type that keeps track of a score. Maybe every time the score grows, it should go up by 2 instead of 1.

Here is how you can do that:

public struct Score
{
    public int Value { get; private set; }

    public Score(int value)
    {
        Value = value;
    }

    public void operator ++()
    {
        Value += 2;
    }

    public void operator --()
    {
        Value -= 2;
    }
}
Enter fullscreen mode Exit fullscreen mode

Now you can write:

var score = new Score(10);
score++;
Console.WriteLine(score.Value); // 12
Enter fullscreen mode Exit fullscreen mode

Nice and smooth.

What about score++ inside expressions

When you write score++ alone, the instance operator works fine. But if you write something like:

var old = score++;
Enter fullscreen mode Exit fullscreen mode

the compiler needs both the old value and the new one. For that, you also need the classic static operator.

Here is the complete version:

public struct Score
{
    public int Value { get; private set; }

    public Score(int value)
    {
        Value = value;
    }

    public void operator ++()
    {
        Value += 2;
    }

    public static Score operator ++(Score s)
    {
        return new Score(s.Value + 2);
    }
}
Enter fullscreen mode Exit fullscreen mode

With both operators in place:

var score = new Score(10);
var old = score++;

Console.WriteLine(old.Value);   // 10
Console.WriteLine(score.Value); // 12
Enter fullscreen mode Exit fullscreen mode

Prefix uses the instance operator. Postfix inside an expression uses the static one. The type now behaves just like built in ones.

Why this is nice

Better performance
The instance operator updates the value directly, so structs avoid extra copies.

Cleaner code
Your custom type feels more natural to work with.

Full control
You decide how your type increments or decrements.

That is a wrap

I hope this post helped you understand how user defined increment and decrement operators work in C# 14. If you give them a try, I would love to hear what you come up with. You can find me on almost every social platform at louella.dev/socials, or you can leave a comment below.

See ya!

Top comments (0)