Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change value inside an (void) extension method

Tags:

c#

unity3d

So I have this mock extension method which change a value to another value:

public static void ChangeValue(this int value, int valueToChange)
{
    value = valueToChange;
}

When I try using it:

int asd = 8;
asd.ChangeValue(10);
Debug.Log(asd);

It returns 8 instead of 10. While the value did change inside the ChangeValue method, it didn't change the value of "asd". What do I need to add to the method, to make it update "asd"?

like image 415
user1979550 Avatar asked Jan 15 '13 07:01

user1979550


5 Answers

You can't do that without using either a return value, or a ref parameter. The latter doesn't work alongside this (extension methods), so your best bet is a return value (rather than void).

like image 115
Marc Gravell Avatar answered Oct 23 '22 12:10

Marc Gravell


The old answer is not valid anymore since newer C# versions support this ref. For further details refer to this answer.

Old Answer:

int is a struct so it's a value-type. this means that they are passed by value not by reference. Classes are reference-types and they act differently they are passed by reference.

Your option is to create static method like this:

public static void ChangeValue(ref int value, int valueToChange)
{
    value = valueToChange;
}

and use it:

int a = 10;
ChangeValue(ref a, 15);
like image 11
Leri Avatar answered Oct 23 '22 11:10

Leri


Old question, but on newer versions of C# it looks like you can now do this for value types by using the this and ref keywords together. This will set value to be the same as valueToChange, even outside of this extension method.

public static void ChangeValue(this ref int value, int valueToChange)
{
    value = valueToChange;
}

I believe this change was made to the compiler on version 15.1, which I think corresponds to C# 7 (or one of its sub versions). I did not immediately find a formal announcement of this feature.

like image 4
Nathanael Avatar answered Oct 23 '22 11:10

Nathanael


According to this answer: https://stackoverflow.com/a/1259307/1945651, there is not a way to do this in C#. Primitive types like int are immutable, and cannot be modified without an out or ref modifier, but the syntax won't allow out or ref here.

I think your best case is to have the extension method return the modified value instead of trying to modify the original.

Apparently this is possible in VB.NET and if you absolutely needed it, you could define your extension method in a VB.NET assembly, but it is probably not a very good practice in the first place.

like image 1
JLRishe Avatar answered Oct 23 '22 12:10

JLRishe


I know it's too late, but just for the record, I recently really wanted to do this, I mean...

someVariable.ChangeValue(10);

...apparently looks way neat than the following (which is also perfectly fine)

ChangeValue(ref someVariable, 10);

And I managed to achieve something similar by doing:

public class MyClass
{
    public int ID { get; set; }
    public int Name { get; set; }
}

public static void UpdateStuff(this MyClass target, int id, string name)
{
    target.ID = id;
    target.Name = name;
}

static void Main(string[] args)
{
    var someObj = new MyClass();    

    someObj.UpdateStuff(301, "RandomUser002");
}

Note that if the argument passed is of reference type, it needs to be instantiated first (but not inside the extension method). Otherwise, Leri's solution should work.

like image 1
Yom T. Avatar answered Oct 23 '22 13:10

Yom T.