18

所以这有效..

public MyClass(ref Apple apple)
{
    apple = new Apple("Macintosh"); // Works fine
}

但是有可能做这样的事情吗?

private Apple myApple;

public MyClass(ref Apple apple)
{
    myApple = apple;
}

public void ModifyApple()
{
    myApple = new Apple("Macintosh"); // does not change the input variable like the first example did
}

当 ref 变量被复制到成员变量myApple时,它似乎失去了它的“ref-ness”并且重新分配它不再改变输入变量。有没有解决的办法?

4

4 回答 4

9

ref-ness 是您传递给函数的函数和参数的参数的属性。通常,它不是变量(甚至字段)的属性。

所以确实,你在那里尝试的东西从一开始就注定了。

于 2011-08-31T06:35:56.647 回答
6

不是真的,不。到下次调用您的代码时,用作方法参数的原始变量甚至可能不再存在:

void Foo()
{
    MyClass x = Bar();
    x.ModifyApple();
}

MyClass Bar()
{
    Apple apple = new Apple();
    return new MyClass(ref apple);
}

这里,apple是一个局部变量,在我们调用的时候已经弹出的堆栈帧中ModifyApple

您确定需要修改原始调用者的变量而不仅仅是更改对象本身吗?

一种伪造的方法是使用包装器类型开始:

public class MutableWrapper<T>
{
    public T Value { get; set; }
}

然后传入 a MutableWrapper<Apple>,并将其存储在您的班级中。然后ModifyApple你可以写:

wrapper.Value = new Apple();

这不会改变调用者的变量,但是下次调用者查看Value属性时,他们会看到你的新苹果。

老实说,这种事情往往会导致代码难以维护,甚至ref不利于可读性。如果你能解释你想要达到的目标的大局,我们也许可以提出一个更好的整体方法。

于 2011-08-31T06:38:14.457 回答
3

不,没有。myApple是一个包含对Apple;的引用的字段 然而,参数apple实际上是对苹果的引用。当您分配applemyApple取消引用参数的值。除此之外,它们是独立且不同的。

所以不:这是不可能的。

可能是这样的:

public class AppleWrapper {
    public Apple Value {get;set;}
}

现在; 如果您存储一个AppleWrapper,则任意数量的调用者都可以访问和更改.Value

于 2011-08-31T06:38:39.720 回答
0

为什么不只ModifyApple返回修改后的 Apple 实例?

public Apple ModifyApple()
{
    myApple = new Apple("Macintosh"); // does not change the input variable like the first example did
    return myApple;
}
于 2011-08-31T06:41:07.420 回答