C # Копирование переменной экземпляра в локальную переменную в функциях того же класса - PullRequest
6 голосов
/ 15 апреля 2010

Недавно я просматривал некоторый код в проекте с открытым исходным кодом и обнаружил много случаев такого кода:

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

Есть ли реальная выгода для создания копии переменной экземпляра?

Ответы [ 6 ]

9 голосов
/ 15 апреля 2010

Возможно, это часть многопоточной программы. Хотя этот код не является потокобезопасным, он гарантирует, что после назначения переменной копирования он не будет изменен другими потоками, и весь код функции после этого будет работать последовательно.

Подобный код с событиями становится критичным в многопоточной среде:

MyEvent e = this.myEvent;

if ( e != null )
{
    e();
}

Здесь, без создания локальной копии, можно получить исключение нулевого указателя, если событие становится нулевым после проверки на нулевое значение и перед вызовом.

7 голосов
/ 15 апреля 2010

Нет, если вы не хотите изменять значение SomeNumber и намереваетесь обновить someNumberCopy. Например, если вы собираетесь зацикливать количество раз и собираетесь уменьшить значение someNumberCopy до нуля, чтобы отслеживать количество.

Я полагаю, что копирование такой переменной может защитить вас от какой-либо внешней функции, изменяющей SomeNumber и изменяющей ее без вашего ведома при выполнении операции. Я мог бы потенциально увидеть это, если класс должен был использоваться в многопоточном приложении. Может быть, не так, как я хотел бы, но это могло быть намерением автора.

1 голос
/ 15 апреля 2010

Может быть полезно, если this.SomeNumber может быть изменен другим потоком, но во время этого метода жизненно важно, чтобы someNumberCopy не мог быть изменен (он может быть не синхронизирован с SomeNumber), тогда может быть жизнеспособным, иначе я не вижу причины для этого.

1 голос
/ 15 апреля 2010

Вы пропустили некоторые важные детали.
Если у вас есть несколько потоков, обращающихся к SomeNumber и этому сценарию:

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

Тогда важно сделать копию.

1 голос
/ 15 апреля 2010

// ... do some work with someNumberCopy что-то делает с someNumberCopy? Это меняет значение? Это передается в метод, который может изменить значение?

Если нет, то нет, выгоды нет.

0 голосов
/ 15 апреля 2010

Единственное преимущество, которое я вижу, это наличие «только для чтения версии» переменной только для этого метода

...