簡體   English   中英

C#lambda ref out

[英]C# lambda ref out

我正在嘗試這樣做,但它不起作用。 一些建議?

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();
                                    };
                    });
}

為什么我不能將test_i設置為3? 我也試過ref和out,但它不起作用。

我該怎么辦才能修復它?

編輯

我試過這個,但是這個方法dataSet的ouside仍然是空的。

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

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

lambda表達式中的i變量指的是方法的參數i 作為一種解決方法,您可以使其引用全局變量(臟解決方案)。

順便說一下, 你不能在lambdas中捕獲refout變量 ,但你可以將它們作為參數。 您需要更改委托的簽名和接收委托的方法的實現,這可能不合適:

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

使用ref關鍵字傳遞變量時,不能在lambda表達式中使用它。 嘗試在lambda中使用局部變量並在其外部分配ref變量(如果可能)(稍微簡化的示例):

private static void Main(string[] args)
{
    int i = 0;
    DoSomethingThatTakesAgesAndNeedsToUpdateUiWhenFinished(ref i);
    Console.WriteLine(i);
}


public static void DoSomethingThatTakesAgesAndNeedsToUpdateUiWhenFinished(ref int i)
{
    int temp = i;
    Thread t = new Thread(() =>
    {
        temp = 3; // assign the captured, local variable    
    });
    t.Start();
    t.Join();

    i = temp; // assign the ref parameter
}

更新
響應更新的答案:您的問題是lambda表達式中的_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方法將在分配_dataSet之前_dataSet執行,因此它將為null 為了解決這個問題,您可能希望使用某種信令機制(例如ManualResetEventAutoResetEvent )來了解分配何時完成。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM