Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
防止对象进入特定状态后被更改?(C#)_C#_Oop_Domain Driven Design - Fatal编程技术网

防止对象进入特定状态后被更改?(C#)

防止对象进入特定状态后被更改?(C#),c#,oop,domain-driven-design,C#,Oop,Domain Driven Design,我有一个我以前从未真正处理过的用例。我有一个对象,在用户单击“保存”后不应更改。最初我创建了两个对象,DraftObject和SavedObject。对于后者,我创建了一个只接受DraftObject并将每个属性设置为受保护集的构造函数 这是可行的,但似乎并不理想。看起来我应该能够在我的对象上设置一个属性来控制其他字段是否可编辑。最好的方法是什么?请原谅我的伪代码,但这正是我所玩弄的: public class MySpecialObject { public virtual s

我有一个我以前从未真正处理过的用例。我有一个对象,在用户单击“保存”后不应更改。最初我创建了两个对象,
DraftObject
SavedObject
。对于后者,我创建了一个只接受DraftObject并将每个属性设置为受保护集的构造函数

这是可行的,但似乎并不理想。看起来我应该能够在我的对象上设置一个属性来控制其他字段是否可编辑。最好的方法是什么?请原谅我的伪代码,但这正是我所玩弄的:

public class MySpecialObject {
        public virtual string MyProperty { get { return MyProperty; } 
            set {
                if (State == "Locked")
                {
                    return;
                } else
                {
                    MyProperty = MyProperty;
                }
            }
         public virtual string State { get { return State; }
            set {
                 if (State == "Locked")
                 {
                     return;
                 } else
                 { 
                   State = State;
                 }
            }

这看起来很难看,尤其是如果我必须对我班上的每一个属性都这样做的话。必须有更好的方法来做到这一点,有什么想法吗?

这实际上是一个相当有趣的问题,因为对于不可变的对象,或者一开始是可变的,但可以锁定为不可变的对象,有很多话要说

具体地说,如果试图设置锁定属性,我认为抛出一个
invalidoOperationException
,可能更有意义。我不知道有什么更干净或更好的方法

编辑


在一篇平行文章中,JLWarlow指出,这正是调用时
SecureString
的工作方式。

如果为了简单起见,它只是一个或两个函数,就按照你写的那样做吧如果你经常这样做,这可能是一个使用AOP的好地方

然后,您将编写一个方面,防止在项目处于特定状态时进行更改

另一个选项几乎和代码一样详细,但可能更好一些,就是必须使用状态设计模式,在这种模式下,每个状态有一个抽象类,每个抽象类的实现不同,因此锁定状态类不允许任何更改


我知道您的示例是伪代码,但也许您可以使用一个布尔属性IsLocked并将其编写得更简单:

set {
          _MyProperty = IsLocked? _MyProperty:value;    
  }

你的方法听起来不错;这就是
SecureString
使用
MakeReadOnly
方法所做的。如果调用方在调用
MakeReadOnly
后试图更改字符串,则会抛出
invalidoOperationException
。这篇文章列出了近十几种不同的.NET面向方面的框架。您有什么特别推荐的吗?Spring.Net拥有庞大的用户群,并且基于Java Spring框架。这里有一篇文章比较了框架,这是一篇有趣的文章,尽管它看起来更倾向于PostSharp而不是Spring.Net。无论如何,+1用于相关的研究和好的想法。文章将PostSharp放得更高,但是Spring.Net更出名,因此更容易学习。这里更简单,其他地方更复杂。
状态
的设置器必须检查
是否处于
锁定状态
,然后将
设置为锁定状态
。不过,其他道具的速度可能会快一点。
IsLocked
本身可以作为属性获取工具。@Ben:嗯,我认为它作为一种方法可能会更好,就像
SecureString.MakeReadOnly
。我这样说是因为永远不可能将
IsLocked
设置为
false
。拥有本身为只读的
IsReadOnly
prop可能仍然有用。在任何情况下,OP都是基于状态锁定,而不是显式锁定。@Steven:除了基于对象的当前状态计算属性的值外,你认为属性获取程序做什么?@Ben:好的,如果
IsLocked
只返回
(state==“Locked”)
,那么这是个好主意。然而,Jonathan没有指定getter,只是指定了一个属性,这意味着一个布尔支持字段。这样一个领域不是一个好主意。