按 volatile 引用类型的值传递

Pass by value of a volatile reference type

我还没有看到与我类似的问题,所以希望我没有遗漏任何问题。

我很好奇 class 中某个字段的 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 参考副本是否仍然 volatileHandleObject 方法中?

我知道,如果我将 HandleObject 的签名更改为 void HandleObject(object syncRoot, ref MyObject myObject),我就会降低波动性,因为 VS 工具提示告诉了我很多。但是如果我只是按值传递,我不会得到 warning/notice。

有没有人有这方面的经验?谢谢,祝你玩得开心。

请注意,当您将 volatile 关键字应用于引用数据类型(即对象)时,它 影响保持对对象的引用的变量(就像非托管 OOP 语言中的 指针 ),而不是该对象内部的内容。

因此,当您将 引用变量 按值传递给方法时,它的内容(对象的地址)被复制并且无需保留波动性 属性 在复制的值上,因为它不会影响被复制的实际变量。

另一方面,如果您将对引用变量的引用传递给方法,该方法能够更改实际传递的引用,这可能会破坏波动性,正如编译器警告您的那样。

为了更好地理解,请查看以下代码。

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