更改(void)扩展方法中的值

use*_*550 13 c# unity-game-engine

所以我有这个模拟扩展方法,它将值更改为另一个值:

public static void ChangeValue(this int value, int valueToChange)
{
    value = valueToChange;
}
Run Code Online (Sandbox Code Playgroud)

当我尝试使用它时:

int asd = 8;
asd.ChangeValue(10);
Debug.Log(asd);
Run Code Online (Sandbox Code Playgroud)

它返回8而不是10.虽然值在ChangeValue方法中发生了变化,但它没有改变"asd"的值.我需要添加到方法中,使其更新为"asd"?

Ler*_*eri 10

int是的,struct所以它是一个value-type.这意味着它们是通过值而不是通过引用传递的.类是reference-types,它们的行为不同,它们通过引用传递.

您可以选择创建这样的静态方法:

public static void ChangeValue(ref int value, int valueToChange)
{
    value = valueToChange;
}
Run Code Online (Sandbox Code Playgroud)

并使用它:

int a = 10;
ChangeValue(ref a, 15);
Run Code Online (Sandbox Code Playgroud)

  • 严格来说,类通常传递"参考值,按值传递" - 它仍然是按值.`ref SomeType`将是"引用值,通过引用传递". (4认同)

Mar*_*ell 9

如果不使用return值或ref参数,则无法执行此操作.后者不兼容this(扩展方法),所以你最好的选择是return价值(而不是void).

  • 除非类型是可变的,否则传递引用类型的@UfukSURMEN是无关紧要的.如果您传入了一个`User`实例并且更改了`user.Name ="New Name";`,则会观察到`.Name`被更改,但引用没有改变.除非引用由`ref`传递,否则将不会注意到对引用本身的更改(`user = new User("Fred")`).现在,在这个例子中,`string`就像`user`,但是`string`是不可变的,所以观察变化的唯一方法是使用`ref` (2认同)

Nat*_*ael 6

老问题,但在较新版本的 C# 上,您现在可以通过同时使用 this 和 ref 关键字来对值类型执行此操作。这会将 value 设置为与 valueToChange 相同,即使在此扩展方法之外也是如此。

public static void ChangeValue(this ref int value, int valueToChange)
{
    value = valueToChange;
}
Run Code Online (Sandbox Code Playgroud)

我相信这一更改是在版本 15.1 上对编译器进行的,我认为该更改对应于 C# 7(或其子版本之一)。我没有立即找到该功能的正式公告。