Moulde
Moulde

Reputation: 3506

Modify ValueType from extension method?

A few days ago I needed to toggle a bool, and I ended up doing like so:

IsVisible = !IsVisible;

I found that to be the simplest way to archive that functionality. But before doing like the example above, I tried out some different ways.

Mostly about using a extension method. Which in my opinion would make it even simpler, or at least less chars to write.

IsVisible.toggle();

But as a boolean is a value type, the bool that is sent though to the extension method is a copy of the original bool, and not a reference type.

public static void Toggle(this boolean value)
{
    value = !value;
}

Which would do what I needed, but as the boolean getting toggled is a copy of the original boolean the change isn't applied to the original...

I tried putting the ref keyword in front of boolean, but that didn't compile. And I still haven't found a reason for that not compiling, wouldn't that be the perfect functionality for extension methods?

public static void Toggle(this ref boolean value)

I even tried casting the boolean into a object, which in my head would make it into a reference type, and then it would no longer be a copy and the change would get passed back. That didn't work either.

So my question is if it's possible to make a extension pass back changes, or another way to make it even simpler than it already is?

I know it quite possible won't get any simpler or more logical than the top example, but you never know :)

Upvotes: 14

Views: 2860

Answers (4)

Oliver
Oliver

Reputation: 824

Since C# 7.2, extension methods can have a mutable "this" reference, as long as the parameter is a value type. See https://github.com/dotnet/csharplang/blob/main/proposals/csharp-7.2/readonly-ref.md#refin-extension-methods

Upvotes: 0

supercat
supercat

Reputation: 81143

In vb.net, extension methods may be declared to accept the implied "this" as a ByRef parameter (equivalent to ref in C#). Such methods work about as one would expect, but for the unfortunate fact that invoking such an extension method on something other than a mutable storage location (e.g. on a property value, readonly storage location, etc.) will cause the compiler silently pass reference to a copy of the parameter, rather than issuing a compilation error [silly behavior, given that 90% of the time the whole point of using a ref parameter would be to be able to modify it at the call site]. Unfortunately, while C# is generally capable of using extension methods written in vb, it won't allow ref parameters to be passed without the ref keyword, and it provides no legal way of specifying ref except when using static-function-call syntax.

Upvotes: 1

Joel Coehoorn
Joel Coehoorn

Reputation: 415690

Primitive types are immutable. You'll have to write your calling code like this:

IsVisible = IsVisible.Toggle();

That's the best you can do with extension methods. No way around it.

Upvotes: 11

obelix
obelix

Reputation: 986

as an aside: wouldn't an extension method be an incredible overhead for something as simple as toggling a bool?

Upvotes: 1

Related Questions