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
}
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;
}
}
Now you can write:
var score = new Score(10);
score++;
Console.WriteLine(score.Value); // 12
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++;
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);
}
}
With both operators in place:
var score = new Score(10);
var old = score++;
Console.WriteLine(old.Value); // 10
Console.WriteLine(score.Value); // 12
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)