将语句lambda作为参数传递

时间:2012-08-17 19:27:43

标签: c# wpf linq lambda

在从另一个线程更新GUI之后关注this question后,我想稍微扩展代码,以便它可以用于除属性赋值之外的其他内容。具体来说,我试图找到一种方法将一些功能直接分配给lambda,以便我可以根据需要定义行为(我为WPF稍微修改了原始内容):

    private delegate void UpdateControlThreadSafeDelegate(Control control, System.Linq.Expressions.Expression<Action> property);
    public void UpdateControl(Control control, System.Linq.Expressions.Expression<Action> property)
    {

        // If calling thread is not associated with control dispatcher, call our thread safe property update delegate
        if (!control.Dispatcher.CheckAccess())
        {
            control.Dispatcher.Invoke(new UpdateControlThreadSafeDelegate(UpdateControl), new object[] { control, property });
        }
        else
        {
            Action call = property.Compile();
            call();
        }
    }

使用方法:

UpdateControl(lbFoo, () => lbFoo.Items.Clear()); // where lbFoo is a ListBox control

这很好用。但我宁愿允许做类似的事情:

UpdateControl(lbFoo, () => { lbFoo.Items.Clear(); lbFoo.Items.Add("Bar");});

这不起作用,返回错误 CS0834:带有语句主体的lambda表达式无法转换为表达式树。错误是明确的,我只是不确定如何最好地继续。我可以按照原来的用法,在几行中做我需要的东西,但它不够整洁。

我猜想有更好/更简单的方法来做我想做的事。

1 个答案:

答案 0 :(得分:5)

如果您不使用表达式,只需传递操作,如下所示:

public void UpdateControl(Control control, Action actionToExecute)

然后你可以按照书面形式使用它。唯一的另一个变化是你的else语句,你可以直接调用它:

   else
    {
        actionToExecute();
    }