如何保存 ref 变量以供以后使用?

发布于 2024-12-02 09:01:47 字数 479 浏览 0 评论 0原文

所以这有效..

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 时,它似乎失去了它的“引用性”,并且重新分配它不再更改输入变量。有办法解决这个问题吗?

So this works..

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

But is it possible to do something like this?

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
}

When the ref variable is copied to the member variable myApple it appears to lose it's 'ref-ness' and re-assigning it no longer changes the input variable. Is there a way around this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

浊酒尽余欢 2024-12-09 09:01:47

ref-ness 是函数参数和传递给函数的参数的属性。一般来说,它不是变量(甚至字段)的属性。

所以事实上,你在那里尝试的事情从一开始就注定是失败的。

ref-ness is a property of parameters of functions and arguments you are passing to functions. It's not a property of variables (or even fields) in general.

So indeed, what you are trying there is doomed from the start.

断肠人 2024-12-09 09:01:47

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

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

然后传入 MutableWrapper,并将其存储在您的类中。然后在 ModifyApple 中,您可以编写:

wrapper.Value = new Apple();

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

老实说,这种事情往往会导致代码难以维护,甚至 ref 的可读性也不是很好。如果您能解释一下您想要实现的目标,我们也许可以建议更好的整体方法。

Not really, no. By the time your code is next invoked, the original variable used as the method argument may no longer even exist:

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

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

Here, apple is a local variable, in a stack frame which will have been popped by the time we call ModifyApple.

Are you sure you need to modify the original caller's variable rather than just changing the object itself?

One way to sort of fake this would be to use a wrapper type to start with:

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

Then pass in a MutableWrapper<Apple>, and store that in your class. Then in ModifyApple you can write:

wrapper.Value = new Apple();

This won't change the caller's variable, but next time the caller looks at the Value property, they'll see your new apple.

To be honest, this sort of thing tends to make for hard-to-maintain code, and even ref isn't great for readability. If you can explain the bigger picture of what you're trying to achieve, we may be able to suggest a better overall approach.

迷途知返 2024-12-09 09:01:47

不,没有。 myApple 是一个保存对 Apple 引用的字段;然而,参数apple实际上是对Apple的引用。当您将 apple 分配给 myApple 时,您取消引用参数的值。除此之外,它们是独立且独特的。

所以不:这是不可能的。

可能是这样的:

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

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

No, there isn't. myApple is a field that holds a reference to an Apple; the parameter apple, however, is actually a reference-to-a-reference-to-an-Apple. When you assign apple to myApple you dereference the value of the parameter. Beyond that, they are separate and distinct.

So no: it is not possible.

What would be possible is to have something like:

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

Now; if you store an AppleWrapper, any number of callers can access and change the .Value

浅黛梨妆こ 2024-12-09 09:01:47

为什么不直接让 ModifyApple 返回修改后的 Apple 实例呢?

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

Why not just have ModifyApple return the modified Apple instance?

public Apple ModifyApple()
{
    myApple = new Apple("Macintosh"); // does not change the input variable like the first example did
    return myApple;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文