7

我最近一直在查看一个开源项目的一些代码,发现这种代码出现了很多次:

class SomeClass
{
    private int SomeNumber = 42;

    public ReturnValue UseSomeNumber(...)
    {
        int someNumberCopy = this.SomeNumber;
        if (someNumberCopy > ...)
        {
            // ... do some work with someNumberCopy
        }
        else
        {
            // ... do something else with someNumberCopy
        }
    }
}

复制实例变量有什么真正的好处吗?

4

6 回答 6

10

这可能是多线程程序的一部分。虽然这段代码不是线程安全的,但它确保了一旦复制变量被赋值,它就不会被其他线程改变,并且此后的所有函数代码都可以一致地运行。

具有事件的类似代码在多线程环境中变得至关重要:

我的事件 e = this.myEvent;

如果 ( e != null )
{
    e();
}

在这里,如果在测试 null 之后和调用之前事件变为 null,则无需制作本地副本,就有可能获得 null 指针异常。

于 2010-04-15T13:30:02.210 回答
8

否,除非您不想更改 SomeNumber 的值并且打算更新 someNumberCopy。就像您要循环次数并将 someNumberCopy 递减到零以跟踪计数一样。

我想像这样复制变量可以保护您免受某些外部函数的影响,这些函数会在执行操作时更改 SomeNumber 并在您不知情的情况下更改它。如果该类应该在多线程应用程序中使用,我可能会看到这一点。也许他不会按照我的方式去做,但这可能是作者的意图。

于 2010-04-15T13:27:53.213 回答
1

是在// ... do some work with someNumberCopy用 someNumberCopy 做些什么吗?它改变了价值吗?它是否被传递给可能会改变值的方法?

如果没有,那么没有,没有任何好处。

于 2010-04-15T13:28:17.060 回答
1

你遗漏了一些重要的细节。
如果您有多个线程访问 SomeNumber 并且这种情况:

    int someNumberCopy = this.SomeNumber;
    if (someNumberCopy > x)
    {
        // do some work with someNumberCopy
        // that relies on (someNumberCopy > x) == true
    }

然后制作副本很重要。

于 2010-04-15T13:37:00.607 回答
1

如果可以由另一个线程修改它可能很有用this.SomeNumber,但是在此方法的持续时间内,someNumberCopy不能更改(它可能与 不同步SomeNumber)至关重要,那么这可能是可行的,否则我看不出原因为了它。

于 2010-04-15T13:38:21.963 回答
0

我看到的唯一好处是仅用于该方法的变量的“只读版本”

于 2010-04-15T13:27:35.890 回答