将锁定设置为null

3
这是合法的吗?(即将锁设置为null)
Class A
{
    public A() { }

    // Some stuff
}

Class B
{
    A a;

    public B()
    {
        A a = new A();
    }

    public void ResetA()
    {
        lock(a)
        {
            if(a != null)
            {
                a = null;
            }
        }
    }
}

我已经编辑了你的标题。请参考“问题的标题应该包含“标签”吗?”,在那里达成共识是“不应该”。 - John Saunders
你想要实现什么目标? - John Saunders
为什么这不应该合法(除了它不能编译)? - Sergey Kalinichenko
你可能想不到一个更糟糕的例子了。如果“这合法吗”意味着“我的代码会崩溃吗?”,那么答案是否定的。C#编译器将生成一个隐藏变量来存储锁对象的引用,因此在解锁时它不会崩溃。如果“这合法吗”意味着“我的代码会出现故障吗?”,那么答案是肯定的。 - Hans Passant
2个回答

3

如果a不是构造函数中的局部变量而是字段,则此操作是合法的。

锁定操作在有效对象上初始化。然后引用被置空,但锁仍然对之前非空值起作用。

但是,如果尝试进行另一个锁定操作,则会出现错误。请参见此问题:为什么C#不允许锁定空值?


0

你可以进行的直接实验表明,lock(null)会抛出ArgumentNullValueException异常。另一个问题是你的代码存在语法错误:

  public void ResetA() {
    lock(a) { ... // <- a is undefined; probably "B" class should have "A a" field 

使用的典型方式是

Class B {
  // Object to be used in locking.
  // It's private: we don't want to let anyone
  // interfere in our internal locking policy 
  // (so we do not use e.g. lock(this) etc)  
  private Object m_SyncObj = new Object();

  A a = new A();

  public void ResetA() {
    lock (m_SyncObj) {
      // A little bit strange lock block unless "a" is locked somewhere else as well
      a = null;
    }
  }
...

嗨,我已经修复了代码并知道如何解决问题(就像您建议的使用m_SyncObj一样),但那不是我的问题。 - Roey Nissim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接