C# lambda 表达式 : How *Not* to Defer "Dereference"?

标签 c# delegates lambda

我正在尝试使用 C# 委托(delegate)实现撤消功能。基本上,我有一个 UndoStack,它维护一个实现每个撤消操作的委托(delegate)列表。当用户选择 Edit:Undo 时,此堆栈弹出第一个委托(delegate)并运行它。每个操作负责将适当的撤消委托(delegate)推送到堆栈。假设我有一个名为“SetCashOnHand”的方法。它看起来像这样:

public void SetCashOnHand(int x) {
    int coh = this.cashOnHand;
    undo u = () => this.setCashOnHand(coh);
    this.cashOnHand = x;
    undoStack.Push(u);
}

因此此方法构造一个撤消委托(delegate),执行操作,然后(假设它成功)将撤消委托(delegate)推送到 UndoStack 上。 (UndoStack 足够聪明,如果在撤消的上下文中调用 undoStack.Push,委托(delegate)将转而进入重做堆栈。)

我的麻烦是将 this.cashOnHand“缓存”到 coh 变量中有点烦人。我希望我可以这样写:

undo u = () => this.setCashOnHand(this.cashOnHand);

当然,这不会得到 cashOnHand 的当前值;它推迟查找值,直到委托(delegate)被调用,所以代码最终什么都不做。除了将值填充到像 coh 这样的局部变量中之外,有什么方法可以在构造委托(delegate)时“取消引用”cashOnHand?

我真的不想听更好的撤消方法。请将此视为关于委托(delegate)的一般性问题,仅使用撤消示例来使问题更清楚。

最佳答案

一般来说,除了您已经在做的事情之外,没有完美的解决方案。

但是,在您的特定情况下,您可以制作 currier ,像这样:

static Action Curry(Action<T> method, T param) { return () => method(param); }

你可以这样使用它:

Curry(setCashOnHand, this.cashOnHand);

如果你的方法接受其他参数,你可以这样使用它:

Curry(cashOnHand => setCashOnHand(3, cashOnHand), this.cashOnHand);

关于C# lambda 表达式 : How *Not* to Defer "Dereference"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2268584/

相关文章:

c# - 如何使用反射调用扩展方法?

c# - 从 C# SONAR 分析中排除生成的代码

c# - Silverlight 和非 UI 线程中的回调

ios - 不同类中的委托(delegate)和数据源可能吗? - UITableView

c# - 我可以使用 Func<object[], object> 委托(delegate)任何类型的参数 input 和 TResult 吗?

c# - LINQ 表达式中的 String.IsNullOrWhiteSpace

c# - Visual Studio - 以编程方式获取启动项目

c# - 如何在C#中存储https POSTmethod的返回值

iOS框架中的委托(delegate)方法

c++ - 这条线是如何打印数组的?