C#对象?只是好奇,是否支持普通C#对象上的事务?就像使用(vartransaction=newObjectTransaction(obj)){try{obj.Prop1=value;obj.Prop2=值;obj.重新计算();//可能触发异常transaction.Commit();//现在obj被保存了}except{transaction.Rollback();//现在obj属性已恢复}}只是为了让答案更有用;-)其他语言有任何相似之处吗?STM更新:这是它的声明:atomic{x++;y--;扔;}将保持x/y不变,包括链式方法调用。看起来像我要求的。至少它非常有趣。我认为这已经足够接近了。还有,其他语言也有类似的东西,比如HaskellSTM。请注意,我没有说它应该在生产中使用;-)Microsoft正在研究它。阅读有关软件事务内存的信息。他们使用了一些不同的语法://对于那些喜欢箭头的人Atomic.Do(()=>{obj.Prop1=value;obj.Prop2=value;obj.Recalculate();});//对于其他喜欢异常的人,请尝试{obj.Prop1=value;obj.Prop2=值;obj.重新计算();}catch(AtomicMarker){}//我们可以在C#中得到这个:atomic{obj.Prop1=value;obj.Prop2=值;obj.重新计算();就其价值而言,成熟的STM有点出路,我强烈建议不要推出自己的STM。幸运的是,您可以通过仔细设计类来获得所需的功能。特别是,不可变类支持开箱即用的类似事务的行为。由于每次设置属性时不可变对象都会返回其自身的新副本,因此如果需要,您始终可以进行完整的历史更改以回滚。JuvalLowy撰写了这篇文章。这是他的原始MSDN文章的链接(我第一次听说这个想法是在他出色的WCF书中)。这是来自MSDN的代码示例,看起来像您想要实现的目标:publicclassMyClass{Transactionalm_Number=newTransactional(3);publicvoidMyMethod(){Transactionalcity=newTransactional("NewYork");使用(TransactionScopescope=newTransactionScope()){city.Value="London";m_Number.Value=4;m_Number.Value++;Debug.Assert(m_Number.Value==5);//不调用scope.Complete(),事务将中止}}您可以在执行方法和设置属性之前复制对象。然后,如果您不喜欢这个结果,您可以“回滚”到副本。当然,假设您没有需要处理的副作用。不,目前.net或C#中没有内置任何内容。但是,根据您的使用要求,您可以实施适合您的方法。您的ObjectTransaction类将序列化(或只是复制)对象并在交易期间保留一份副本。如果调用commit可以删除副本,但如果调用rollback则可以从副本恢复原始对象的所有属性。这个建议有很多注意事项。总而言之,我几年前从事的一个项目确实做了类似的事情。在非常严格的约束下,它工作得很好。我们只支持内部业务层数据对象。它们都必须继承自一个基本接口,该接口提供一些关于属性类型的额外元数据,并具有关于哪些事件可以从属性设置器触发的规则。我们将启动事务,然后将对象绑定到GUI。如果用户点击确定,事务就关闭了,但如果他们点击取消,事务管理器就会解除与GUI的绑定,并回滚对象上的所有更改。不,今天对普通托管对象不存在这种类型的支持。同样,简单的解决方案是首先不允许您的对象进入无效状态。然后你不需要回滚任何东西,你不需要调用“验证”等。如果你删除你的setter并开始考虑向对象发送消息来对内部数据做一些事情,而不是设置属性,你会发现有关您的领域的微妙之处,否则您将无法发现。这是我刚刚写的解决方案:)也应该使用数组和任何引用类型。以上就是C#学习教程:TransactionofC#objects?所有分享的内容,如果对你有用,需要了解更多C#学习教程,希望大家多多关注——publicsealedclassObjectTransaction:IDisposable字典sourceObjRefHolder;对象m_backup;对象m_original;publicObjectTransaction(objectobj){sourceObjRefHolder=newDictionary();m_backup=processRecursive(obj,sourceObjRefHolder,newCreateNewInstanceResolver());m_original=对象;}publicvoidDispose(){Rollback();}publicvoidRollback(){if(m_isDisposed)return;varprocessRefHolder=newDictionary();vartargetObjRefHolder=sourceObjRefHolder.ToDictionary(x=>x.Value,x=>x.Key);varoriginalRefResolver=newDictionaryRefResolver(targetObjRefHolder);processRecursive(m_disbackup,processRefHolder);();}publicvoidCommit(){如果(m_isDisposed)返回;//什么也不做}voiddispose(){sourceObjRefHolder=null;m_backup=空;m_original=null;m_isDisposed=真;}objectprocessRecursive(objectobjSource,DictionaryprocessRefHolder,ITargetObjectResolvertargetResolver){if(objSource==null)返回null;如果(objSource.GetType()==typeof(string)||objSource.GetType().IsClass==false)返回objSource;如果(processRefHolder.ContainsKey(objSource))返回processRefHolder[objSource];类型type=objSource.GetType();对象objTarget=targetResolver.Resolve(objSource);processRefHolder.Add(objSource,objTarget);if(type.IsArray){数组objSourceArray=(Array)objSource;数组objTargetArray=(Array)objTarget;for(inti=0;ifieldsInfo=FieldInfoEnumerable.Create(type);foreach(FieldInfofinfieldsInfo){if(f.FieldType==typeof(ObjectTransaction))continue;objectobjSourceField=f.GetValue(objSource);objectobjTargetField=processRecursive(objSourceField,processRefHolder,targetResolver);f.SetValue(objTarget,objTargetField);}}returnobjTarget;}interfaceITargetObjectResolver{objectResolve(objectobjSource);}类CreateNewInstanceResolver:ITargetObjectResolver{publicobjectResolve(objectsourceObj){objectnewObject=null;如果(sourceObj.GetType().IsArray){varlength=((Array)sourceObj).Length;newObject=Activator.CreateInstance(sourceObj.GetType(),length);}else{//没有调用构造函数,所以在实例化过程中没有副作用newObject=System.Runtime.Serialization.FormatterServices.GetUninitializedObject(sourceObj.GetType());//newObject=Activator.CreateInstance(sourceObj.GetType());}返回新对象;}}类DictionaryRefResolver:ITargetObjectResolver{readonlyDictionarym_refHolder;publicDictionaryRefResolver(DictionaryrefHolder){m_refHolder=refHolder;}publicobjectResolve(objectsourceObj){if(!m_refHolder.ContainsKey(sourceObj))thrownewException("Unknownobjectreference");返回m_refHolder[sourceObj];}}}classFieldInfoEnumerable{publicstaticIEnumerableCreate(Typetype){while(type!=null){varfields=type.GetFields(BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Instance);foreach(FieldInfofiinfields){yieldreturnfi;}type=type.BaseType;}}}侵权请点右联系管理员删除如需转载请注明出处:
