c# - C# 是否有办法在小范围内模拟软件事务内存?

标签 c# .net

C# 是否有办法在特定范围内临时更改变量的值并在范围/ block 结束时自动将其还原?

例如(不是真正的代码):

bool UpdateOnInput = true;

using (UpdateOnInput = false)
{
    //Doing my changes without notifying anyone
    Console.WriteLine (UpdateOnInput) // prints false
}
//UpdateOnInput is true again.

编辑:

我想要上面的原因是因为我不想这样做:

UpdateOnInput = false

//Doing my changes without notifying anyone
Console.WriteLine (UpdateOnInput) // prints false

UpdateOnInput = true

最佳答案

不,没有办法直接这样做。关于如何做这类事情有几种不同的思想流派。比较和对比这两个:

originalState = GetState();
SetState(newState);
DoSomething();
SetState(originalState);

对比

originalState = GetState();
SetState(newState);
try
{
    DoSomething();
}
finally
{
    SetState(originalState);
}

很多人会告诉你,后者“更安全”。

不一定如此。

两者的区别当然是后者即使DoSomething()抛出异常也恢复状态。这比在异常情况下保持状态变化更好吗? 是什么让它变得更好?您有一个意外的、未处理的异常报告发生了一些可怕意外的事情。你的内部状态可能完全不一致并且被任意搞乱了;没有人知道在异常发生时可能发生了什么。我们所知道的是 DoSomething 可能试图对变异状态做些什么。

在发生可怕和未知的事情的情况下,继续搅动那个特定的锅并试图改变刚刚导致异常的状态再次真的是正确的做法吗?

有时这是正确的做法,有时却会使事情变得更糟。您实际处于哪种情况取决于代码究竟在做什么,因此在盲目选择一个或另一个之前,请仔细考虑正确的做法是什么。

坦率地说,我宁愿先不陷入困境来解决问题。我们现有的编译器设计使用了这种设计模式,坦率地说,它非常令人恼火。在现有的 C# 编译器中,错误报告机制是“副作用”。也就是说,当编译器的一部分出现错误时,它会调用错误报告机制,然后将错误显示给用户。

这是 lambda 绑定(bind)的主要问题。如果你有:

void M(Func<int, int> f) {}
void M(Func<string, int> f) {}
...
M(x=>x.Length);

那么它的工作方式就是我们尝试绑定(bind)

M((int x)=>{return x.Length;});

M((string x)=>{return x.Length;});

然后我们看看哪一个(如果有的话)给了我们一个错误。这种情况下,前者报错,后者编译无错,所以这是合法的lambda转换,重载决议成功。 我们如何处理错误?我们无法将其报告给用户,因为该程序没有错误!

因此,当我们绑定(bind) lambda 的主体时,我们所做的正是您所说的:我们告诉错误报告器“不要向用户报告您的错误;而是将它们保存在此处的缓冲区中”。然后我们绑定(bind) lambda,将错误报告器恢复到之前的状态,并查看错误缓冲区的内容。

我们可以完全避免这个问题,方法是更改​​表达式分析器,使其将错误与结果一起返回,而不是使错误成为与状态相关的副作用。这样就完全不需要更改错误报告状态,我们甚至不必担心它。

因此,我鼓励您重新审视您的设计。有没有一种方法可以让你正在执行的操作不依赖于你正在改变的状态?如果是,那就那样做,然后你就不用担心如何恢复变异状态了。

(当然,在我们的例子中,我们确实希望在发生异常时恢复状态。如果在 lambda 绑定(bind)过程中编译器内部抛出某些东西,我们希望能够将其报告给用户!我们不希望错误报告器停留在“抑制报告错误”状态。)

关于c# - C# 是否有办法在小范围内模拟软件事务内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2275483/

相关文章:

c# - 正则表达式单词边界和匹配项之间的距离

c# - 带有超链接列的 GridView

c# - 如何检索 LoaderExceptions 属性?

c# - 何时创建通用类和部分类

c# - Asp.Net MVC - 如何为 ChildAction 保存 ModelState?

c# - 移位位移返回错误结果

c# - 如何检查字符数组中是否存在特定字符

c# - 避免绑定(bind)中的转换器

c# - Xamarin Forms 异步播放声音

.net - 使用设计时的声明性数据上下文和运行时的数据模板连接 MVVM View 和 View 模型?