我在一个类中有一个属性,当它被设置时,它将改变一些其他属性的值,其中任何一个都可能引发一个特定的回滚事件(比如RollbackEvent
)。如果此类事件被触发,则原始属性所做的所有更改都已回滚,现在我需要该属性停止在其轨道上。
抛出异常不是一个选项(我认为)'因为会有另一个程序集消耗代码(实际上是另一个程序集在我的代码中捕获第二个事件,如果它无法处理情况,它命令我的代码回滚,并且在启动RollbackEvent的时候),不应该抛出任何异常。
这是我的代码的一般概述,而AFAIK第二个程序集中的代码永远不会意识到在第一个程序中抛出异常,但是在“事务”之后回滚(显然)成功的代码就在第二个集会停止执行。
汇编1
public class Someclass
{
public String SomeField
{
get { return this._someField; }
set
{
try
{
this.BackupSomeFields();
this._someField = value;
//Some other Properties are changed
//One of which may (and will for the purposes of the question) throw a DocumentRolledbackException exception
}
catch (DocumentRolledbackException ex)
{
return;
}
}
}
public String SomeOtherField
{
get { return this._someOtherField; }
set
{
this._someOtherField = value;
//Raise AN event (handled in Assembly 2)
}
}
public void RollbackProcessTransaction()
{
//Rollback changes with the backup created by the SomeField property
//Raise THE event
DocumentRolledBack(this, new EventArgs());
}
private void MyBase_DocumentRolledBack(Object sender, EventArgs e)
{
//This method is called when the DocumentRolledBack event is fired in the RollbackProcessTransaction method.
throw new DocumentRolledbackException(this);
}
}
大会2
public class SomeOtherClass
{
private SomeClass obj;
private HandleANEvent()
{
obj.RollbackProcessTransaction();
//Code in this line on never gets executed! >.<
}
}
基本上它一切正常,当在程序集1中抛出异常时,它会被属性捕获,然后这样的属性返回,但调用obj.RollbackProcessTransaction();
之后的代码永远不会被执行...为什么?< / p>
PS 我在编辑器中编写了所有代码,因为我实际上是用VB编程的,所以不要把所有代码都放在那里,这只是为了让你理解。 / p>
答案 0 :(得分:1)
喜欢这个吗?
public class Test
{
public object Foo1
{
try
{
Foo2 = 1;
Foo3 = 2;
Foo4 = 3;
}
catch (RollbackException ex) { }
}
private void DoRollback()
{
throw new RollbackException();
}
public object Foo2 { get; set; }
public object Foo3 { get; set; }
public object Foo4 { get; set; }
private class RollbackException : Exception
{
}
}
编辑:
public class SomeOtherClass
{
private SomeClass obj;
public SomeOtherClass()
{
var backup = obj.Clone();
try
{
obj.SomeField = "test";
}
catch (RollbackException ex)
{
obj = backup;
}
}
}
答案 1 :(得分:1)
最简单的方法是在更改之前记录每个属性的值,然后在发生错误时将其还原。如果每个属性都有一个快速退出,如果值设置相同,它将防止抛出进一步的异常。我从Magnus的回答中借了一点。
public class Test
{
public object Foo1
{
object oldfoo2 = Foo2;
object oldfoo3 = Foo3;
object oldfoo4 = Foo4;
try
{
Foo2 = 1;
Foo3 = 2;
Foo4 = 3;
}
catch (RollbackException ex) {
Foo4 = oldfoo4;
Foo3 = oldfoo3;
Foo2 = oldfoo2;
}
}
public object Foo2 {
get {
return foo2;
}
set {
if (value == foo2) return;
if (isInvalid(value)) throw new RollbackException();
foo2 = value;
}
}
private object foo2 = null;
public object Foo3 { /* As Foo2 */ }
public object Foo4 { /* As Foo2 */ }
private class RollbackException : Exception
{
}
}