为什么 C# 编译器复制变量进行锁定?

Why C# compiler copies variable for locking?

我原来的代码是这样的

Object mylock = new object();
void Test()
{
    lock(mylock)
    {
        
    }
}

编译成如下代码

void Test
{
    object obj = mylock;  // add a temporary variable
    bool lockTaken = false;
    try
    {
        Monitor.Enter(obj, ref lockTaken);
    }
    finally
    {
        if (lockTaken)
        {
            Monitor.Exit(obj);
        }
    }
}

我想知道为什么添加一个临时变量而不是直接使用原始变量如下。

void Test
{
    bool lockTaken = false;
    try
    {
        Monitor.Enter(mylock, ref lockTaken);  // use original variable directly
    }
    finally
    {
        if (lockTaken)
        {
            Monitor.Exit(mylock);  // use original variable directly
        }
    }
}

几个 C# 构造(usinglock)以这种方式转换为最终代码,以防止重新分配所使用的变量。您真的不希望 finally 部分对与原始操作开始时的值不同的值起作用。

如果编译器仅在 finally 部分使用 myLock 的当前值,将出现错误的代码示例:

 object myLock = new object();

 lock(myLock)
 {
    myLock = new object(); 
    ...
 }

请注意,编译此类代码也会带来 CS0728 警告,因为尝试更改锁定变量将被忽略。