锁定对象以防止任何数据更改

时间:2011-05-26 13:31:54

标签: c#

有点奇怪......

假设我有以下课程:

public class Wibble
{
  public string Foo {get;set;}
  public string Bar {get;set;}
}

此类用于更新/更改Foo和Bar值的过程。但是,在进程中的某个点之后,我想“锁定”实例以防止进行任何更改。那么问题是如何最好地做到这一点?

各种解决方案都是这样的:

public class Wibble
{
  private string _foo;
  private string _bar;

  public bool Locked {get; set;}

  public string Foo
  {
    get
    {
      return this._foo
    }
    set
    {
        if (this.Locked)
        {
          throw new ObjectIsLockedException()
        }

        this._foo = value;
    }
  }

  public string Bar
  {
    get
    {
      return this._bar
    }
    set
    {
        if (this.Locked)
        {
          throw new ObjectIsLockedException()
        }

        this._bar = value;
    }
  }
}

然而,这似乎有点不雅。

想要这样做的原因是我有一个应用程序框架,它使用外部开发的使用该类的插件。 Wibble类被传递到插件中,但是其中一些应该永远不会改变内容,其中一些可以。这背后的意图是捕获开发集成问题而不是运行时生产问题。使对象“锁定”允许快速识别未按指定编码的插件。

4 个答案:

答案 0 :(得分:2)

我已经实现了类似于你的锁定模式的东西,但也有一个由包含实际类数据的私有子类实现的只读接口,这样你就可以传递出一个只读的只读视图这些数据无法升级到原始的“可变版本”。锁定纯粹是为了防止数据提供者在提供不可变视图后进行进一步的更改。

它运作得相当好,但有点尴尬,正如你所指出的那样。我认为拥有可变的'Builder'对象实际上更加清晰,然后可以生成不可变的快照。想想StringBuilder和String。这意味着您复制了一些属性代码并且必须编写例程来进行复制,但在我看来,与在每个属性上进行写锁定相比,它不那么尴尬。在编译时也很明显,快照应该是只读的,而Builder的用户不能修改它之前创建的快照。

答案 1 :(得分:1)

我建议这样做:

不可变的基类:

public class Wibble
{
  public string Foo { get; private set; }
  public string Bar { get; private set; }

  public Wibble(string foo, string bar)
  {
    this.Foo = foo;
    this.Bar = bar
  } 
}

然后是一个可以改变的可变类,然后在时机成熟时创建一个不可变的副本。

public class MutableWibble 
{
  public string Foo { get; set; }
  public string Bar { get; set; }

  public Wibble CreateImmutableWibble() 
  {
    return new Wibble(this.Foo, this.Bar);
  }
}

我完全不记得C#语法,但你明白了。

进一步阅读:http://msdn.microsoft.com/en-us/library/acdd6hb7%28v=vs.71%29.aspx

答案 2 :(得分:0)

你不能让一个对象不可变!

您可以关注此帖:

How do I create an immutable Class?

但我认为你总是可以通过反思改变属性值!

<强>更新

“......实际上,字符串对象不是那样的 不可变的,据我所知,至少有两种方法可以打破字符串 不变性。使用此代码示例所示的指针以及一些高级System.Reflection用法......“

http://codebetter.com/patricksmacchia/2008/01/13/immutable-types-understand-them-and-use-them/

答案 3 :(得分:0)

您拥有的另一个选项是使用BinaryFormatter创建要“锁定”的对象的成员克隆。虽然您没有锁定对象,但您正在创建一个快照,当原始文件保持不变时可以将其丢弃。