Передача по значению типа энергозависимой ссылки - PullRequest
0 голосов
/ 18 декабря 2018

Я не видел вопросов, похожих на мои, поэтому надеюсь, что ничего не пропустил.

Мне любопытно, сохраняется ли свойство volatile поля внутри класса при передачеэто поле по значению (то есть создается ссылка на локальную копию, которая указывает на исходный объект).

Предупреждения VS в значительной степени говорят мне, что передача по ссылке на поле volatile не сохраняет волатильностьЭто.Но мне было интересно, если при передаче по значению сохраняется свойство volatile.

Примеры кода, иллюстрирующие проблему:

class static Singleton
{
     private static volatile MyObject myObject;
     private static readonly object syncRoot = new object();

     public static MyObject My => HandleObject(syncRoot, myObject);

     private void HandleObject(object syncRoot, MyObject myObject)
     {
          if(myObject.SomeProperty) //is the myObject reference still volatile? 
          { /* some other code */ }
     }
}

Как я уже говорил выше, мой вопрос: myObject справочная копия по-прежнему volatile в методе HandleObject?

Я знаю, что если я изменю сигнатуру HandleObject на void HandleObject(object syncRoot, ref MyObject myObject), я потеряю волатильность, поскольку подсказка VS говорит мне об этом.Но я не получаю предупреждения / уведомления, если я просто передаю по значению.

У кого-нибудь есть опыт с этим?Спасибо и хорошего.

1 Ответ

0 голосов
/ 18 декабря 2018

Обратите внимание, что когда вы применяете ключевое слово volatile к ссылочному типу данных (т.е. объекту), оно только влияет на переменную, которая сохраняет ссылку на объект (например, указатель *)1005 * в неуправляемых языках ООП), а не то, что находится внутри этого объекта.

Таким образом, когда вы передаете методическую переменную в качестве значения методу, его содержимое (адрес объекта)копируется, и нет необходимости сохранять свойство volatility для скопированного значения, поскольку оно не повлияет на фактическую копируемую переменную.

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

Для лучшего понимания взгляните на следующий код.

class SomeClass {
    private volatile Object myObject = new Object();

    private void HandleObject(Object theObject) {
        // The `theObject` argument is a copy of the passed variable
        // and the following line won't change the actual variable's
        // value, but the local instance.
        theObject = new Object();
    }

    private void HandleObjectRef(ref Object theObject) {
        // The actual variable's value will be changed, when the
        // following line is executed.
        theObject = new Object();
    }

    public void DoSomething() {
        // This call is safe, the `myObject` variable won't be
        // changed after when `HandleObject` is executed.
        this.HandleObject(myObject);

        // The `myObject` will be changed after when `HandleObjectRef`
        // is executed. (WARNING)
        this.HandleObjectRef(ref myObject);
    }
}
...