2011-05-02 27 views
3

我有以下代碼:使用未分配的本地變量? C#

 double ticketPrice; 
     LoadOperation loGetTickets = ticketClass.loadTickets(); 
     loGetTickets.Completed += (s, args) => 
     { 
      foreach (Web.Ticket tt in ticketClass.getContext()) 
      { 
       if (tt.bookingId == data.bookingId) 
       { 
        pView.lblTicketAmount.Content = "£" + tt.ticketPrice; 
        MessageBox.Show("Price: " + tt.ticketPrice); 
        ticketPrice = Convert.ToDouble(tt.ticketPrice); 
        pView.lblTicketName.Content = tt.ticketName; 
        break; 
       } 
      } 
     }; double subTotal = ticketPrice + ticketQuantity; 

當我運行它,我得到的錯誤:使用未分配的局部變量的「ticketPrice」

正如你可以看到它得到賦值,從循環。

如果我使用:

double ticketPrice = 0.0; 

錯誤去卻對值停留在0.0,但我不明白,因爲在MessageBox出現每次和輸出值,所以我會承擔值爲tt.ticketPrice正在填充ticketPrice

任何人都可以幫助我解決這個問題。

感謝

+0

我從來沒有看到一個運行時錯誤「使用未分配的本地變量」只是一個編譯時錯誤的排序。 – 2011-05-02 21:34:11

+1

這是一個詭計問題嗎?賦值在兩行之後使用'ticketPrice'的值。 – 2011-05-02 21:34:11

+3

@所有交易:呃不,它不會 - 'tt.ticketPrice'與'ticketPrice'沒有關係(除了類似的名字)。 – rsenna 2011-05-02 21:42:34

回答

3

您的意思是ticketPrice的值保持爲零,但代碼不顯示讀取變量值的地方!

如果在您發佈的代碼片段後面的某些代碼中使用了該行爲,則該行爲將有意義。例如: -

double ticketPrice;   
LoadOperation loGetTickets = ticketClass.loadTickets();   
loGetTickets.Completed += (s, args) => { 
    // Set value of 'ticketPrice' 
    ticketPrice = ... 
}; 

// Use the value of the variable 
Console.WriteLine(ticketPrice); // (*) 

這是不行的,因爲標記爲(*)行實際完成之前在Completed處理程序設置變量的值。爲了使它工作,您需要將使用該變量的代碼移到處理程序中(在設置變量值的代碼之後)。

然後,當然,在方法中聲明變量是沒有意義的,因爲它只會用在lambda函數的主體中,所以最終會出現如下結果:

LoadOperation loGetTickets = ticketClass.loadTickets();   
loGetTickets.Completed += (s, args) => { 
    double ticketPrice;   
    // Set value of 'ticketPrice' 
    ticketPrice = ... 

    // Use the value of the variable 
    Console.WriteLine(ticketPrice); // (*) 
}; 

我相信你剛剛在C#4中發現了異步編程的痛點:-)。這就是爲什麼F#支持異步工作流(您可以在事件處理程序中編寫相同的代碼)以及爲什麼C#設計人員正在考慮將來向C#添加類似的東西。

+0

好的,我明白你,因爲查詢還沒有完成處理,它沒有時間在代碼完成執行之前在ticketPrice中使用tt.ticketPrice? – 2011-05-02 21:50:56

+0

好的,我只是將計算移入事件。現在有效,但我想我必須儘量避免這種情況。謝謝(你的)信息! – 2011-05-02 21:56:13

+0

@Sandeep:是的,這正是問題所在。處理程序不能保證在main方法的執行轉移到下一行之前完成(並使用'ticketPrice')。當啓動一些異步操作(需要一個處理程序)時,調用方法的其餘部分通常不需要包含太多的代碼。 – 2011-05-02 22:11:51

1

雖然ticketPrice並在循環獲取設置,它是在事件處理中。由於該事件有可能永遠不會觸發(就編譯器而言),它會將其視爲未分配,直到遇到保證運行的行。

0

double ticketPrive;聲明移到foreach之內,一切都會好的。

+0

如果它出現在foreach中,問題出現的原因是爲什麼它首先出現? – BrokenGlass 2011-05-02 21:38:22

+0

它只能在lambda表達式內部使用,所以將它移動到那裏! – 2011-05-02 21:40:00

+0

這是不正確的,它也可以在事件處理程序之外使用。但是,當然你必須等到事件發生。 – Guffa 2011-05-02 21:53:38

0

該變量確實被賦值,但會在稍後發生。

用於分配變量的代碼位於事件處理程序中,以便在事件發生之前代碼不會運行,並且在加載故障單之後。

如果您嘗試立即使用該變量,它將不會被設置。事件發生之後才能使用該變量。最簡單的方法是將使用變量的代碼放入事件處理程序中。