18

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

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

当我尝试使用它时:

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

它返回 8 而不是 10。虽然值在 ChangeValue 方法中确实发生了变化,但它并没有改变“asd”的值。我需要向该方法添加什么以使其更新“asd”?

4

6 回答 6

12

如果不使用return值或ref参数,您将无法做到这一点。后者不能与this(扩展方法)一起工作,所以你最好的选择是一个return值(而不是void)。

于 2013-01-15T07:54:39.193 回答
11

由于较新的 C# 版本支持this ref. 有关更多详细信息,请参阅此答案。

老答案:

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

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

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

并使用它:

int a = 10;
ChangeValue(ref a, 15);
于 2013-01-15T07:54:53.457 回答
3

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

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

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

于 2020-10-22T17:40:29.640 回答
1

根据这个答案:https://stackoverflow.com/a/1259307/1945651,在 C# 中没有办法做到这一点。像这样的原始类型int是不可变的,没有outorref修饰符就不能修改,但是这里的语法不允许outor ref

我认为您最好的情况是让扩展方法返回修改后的值,而不是尝试修改原始值。

显然这在 VB.NET 中是可能的,如果你绝对需要它,你可以在 VB.NET 程序集中定义你的扩展方法,但这可能不是一个很好的做法。

于 2013-01-15T07:56:09.503 回答
1

我知道为时已晚,但为了记录,我最近真的很想这样做,我的意思是......

someVariable.ChangeValue(10);

...显然看起来比下面的要整洁(这也很好)

ChangeValue(ref someVariable, 10);

我设法通过以下方式实现了类似的目标:

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");
}

请注意,如果传递的参数是引用类型,则需要先对其进行实例化(但不在扩展方法内部)。否则,Leri 的解决方案应该有效。

于 2016-08-18T04:35:35.787 回答
0

因为int 是值类型,所以当你在函数中传递它时,它是按值复制的。

要查看函数外部的更改,请将其重写为:

public static int ChangeValue(this int value, int valueToChange)
{
    //DO SOMETHING ;

    return _value_; //RETURN COMPUTED VALUE 
}

可以使用ref keyowrd,但它不能应用于带有 的参数this,因此在您的情况下,只需返回结果值。

于 2013-01-15T07:55:31.337 回答