C#lambda参考输出

C#lambda参考输出,c#,.net,.net-3.5,lambda,C#,.net,.net 3.5,Lambda,我试着这么做,但没用。有什么建议吗 int test_i = 0; DoSomethingThatTakesAgesAndNeedsToUpdateUiWhenFinished(test_i); test_i <- still is 0 and not 3!!! public void DoSomethingThatTakesAgesAndNeedsToUpdateUiWhenFinished(int i) { DisableUi(); m_commandExecutor

我试着这么做,但没用。有什么建议吗

int test_i = 0;
DoSomethingThatTakesAgesAndNeedsToUpdateUiWhenFinished(test_i);
test_i <- still is 0 and not 3!!!

public void DoSomethingThatTakesAgesAndNeedsToUpdateUiWhenFinished(int i)
{
    DisableUi();
    m_commandExecutor.ExecuteWithContinuation(
                () =>
                    {
                        // this is the long-running bit
                        ConnectToServer();
                        i = 3; <-------------------------- 
                        // This is the continuation that will be run
                        // on the UI thread
                        return () =>
                                    {
                                        EnableUi();
                                    };
                    });
}

lambda表达式中的
i
变量引用方法的参数
i
。作为一种解决方法,您可以使其引用全局变量(脏解决方案)

顺便说一下,但是你可以把它们作为参数。您需要更改代理的签名和接收代理的方法的实现,这可能不合适:

(out int i) => { i = 10; }

使用
ref
关键字传递变量时,不能在lambda表达式中使用它。如果可能,尝试在lambda内部使用局部变量,并在其外部指定
ref
变量(稍微简化的示例):

更新
作为对更新答案的回应:您的问题是lambda表达式内部的
\u dataSet
与lambda表达式外部的dataSet不是同一个变量。您可以执行以下操作:

class DataSetContainer
{
    public DataSet DataSet { get; set; }
}
现在,我们有了一个引用类型,它具有一个可以在lambda表达式中安全修改的属性:

public static void Select(DataGridView dataGridView,
                          DataSetContainer dataSetContainer, 
                          params object[] parameters)
{
    AsyncCommandExecutor commandExecutor = new AsyncCommandExecutor(System.Threading.SynchronizationContext.Current);
    commandExecutor.ExecuteWithContinuation(
    () =>
    {
        // this is the long-running bit
        dataSetContainer.DataSet = getDataFromDb(parameters);

        // This is the continuation that will be run on the UI thread
       return () =>
       {
           dataGridView.DataSource = _dataSet.Tables[0].DefaultView;
       };
    });

}
}

在上面的代码中,lambda表达式将更新传递给
Select
方法的
DataSetContainer
实例的
DataSet
属性。由于您不是在修改传递的参数本身,而是只修改该实例的一个成员,因此不需要使用
ref
关键字,而且我们还绕过了闭包问题

更新2

现在,当我打开我的大脑时,我意识到
Select
方法发出一个异步调用。很可能代码看起来最后一行是
Select
方法将在
\u dataSet
分配之前很久执行,因此它将
null
。为了解决这个问题,您可能需要研究使用某种信号机制(例如
ManualResetEvent
AutoResetEvent
)来了解分配何时完成。

是否可以像我的示例中那样使用它,但使用数据集而不是int i?@Jooj:如果传递引用类型,您应该能够在lambda表达式中修改其成员属性/字段。我更新了答案。希望有帮助:o)
class DataSetContainer
{
    public DataSet DataSet { get; set; }
}
public static void Select(DataGridView dataGridView,
                          DataSetContainer dataSetContainer, 
                          params object[] parameters)
{
    AsyncCommandExecutor commandExecutor = new AsyncCommandExecutor(System.Threading.SynchronizationContext.Current);
    commandExecutor.ExecuteWithContinuation(
    () =>
    {
        // this is the long-running bit
        dataSetContainer.DataSet = getDataFromDb(parameters);

        // This is the continuation that will be run on the UI thread
       return () =>
       {
           dataGridView.DataSource = _dataSet.Tables[0].DefaultView;
       };
    });

}