2011-11-23 59 views
1

我有一個問題讓我很困惑。在我的類的構造函數中,我創建了一個SeatManager.cs實例,它包含兩個數組(字符串和雙精度)。在方法btnReserveCancel_Click我試圖用數據填充這兩個數組。但是當我稍後調用UpdateGUI()方法時,會創建SeatManager.cs的另一個實例(當我需要另一件事情的幫助時,我的老師添加了這行代碼),並且當發生這種情況時,我剛剛填入這兩個數組的所有數據都會得到丟失!奇怪的部分是,如果我刪除了在UpdateGUI()中創建新實例的那一行,那麼編譯器就會向我發出警告,說有什麼不對。調用對象的一個​​實例

爲什麼UpdateGUI()在btnReserveCancel_Click不需要時需要SeatManager.cs的新實例?爲什麼在實例變量中有一個可用的時候,UpdateGUI()需要一個SeatManager.cs的新實例?

private double revenue = 0.0; 
    private const int totalNumOfSeats = 10; 
    private int numOfReservedSeats = 0; //Increases every time a new reservation is made 
    const double minLimit = 10; 
    const double maxLimit = 50; 
    private SeatManager seatMngr; 

    public MainForm() 
    { 
     InitializeComponent(); 
     InitializeGUI(); 
     seatMngr = new SeatManager(totalNumOfSeats);//skapar en instans av klassen SeatManager 
     UpdateGUI(); 
    } 



    private void btnReserveCancel_Click(object sender, EventArgs e) 
    { 
     if (rbtnReserved.Checked == true)//Om radiobutton RESERVE är iklickad 
     { 
      string customerName = string.Empty; 
      double seatPrice = 0.0; 

      int selection = listBox1.SelectedIndex; 
      if (selection == -1) 
      { 
       MessageBox.Show(string.Format("You must select which seat you want to reserve!"), "Select a seat.", MessageBoxButtons.OK, MessageBoxIcon.None); 

      } 
      else 
      { 
       string getSeatNumber = listBox1.SelectedItem.ToString();//Tar första bokstaven i den markerade strängen i listboxen och gör om till index. 
       int seatNumber = int.Parse(getSeatNumber.Substring(0, 1)); 

       bool inputOk = ReadAndValidateInput(out customerName, out seatPrice); 
       bool validSeats = CheckVacantSeats(); 

       if (inputOk && validSeats) 
       { 
        if (seatMngr.ReserveSeat(customerName, seatPrice, seatNumber) != true) 
        { 
         var result = MessageBox.Show(string.Format("Do you wish to overwrite reservation? "), "Seat already registered", MessageBoxButtons.YesNo, MessageBoxIcon.None); 
         if (result == DialogResult.Yes) 
         { 
          double amount = seatMngr.GetPaidPrice(seatNumber); 
          MoneyBackWhenCancelOrOverwrite(amount); 
          seatMngr.ReserveSeatOverwrite(customerName, seatPrice, seatNumber); 
          revenue += seatPrice; 
         } 
        } 
        else 
        { 
         seatMngr.ReserveSeat(customerName, seatPrice, seatNumber); 
         numOfReservedSeats++; 
         revenue += seatPrice; 
         if (seatMngr.ReserveSeat(customerName, seatPrice, seatNumber) == true) 
         { 
          MessageBox.Show(string.Format("Det funkade "), "Sfgdfg", MessageBoxButtons.OK, MessageBoxIcon.None); 
         } 
        } 
       } 
      } 
     } 
     else if (rbtnCancel.Checked == true)//Om radiobutton CANCEL är iklickad. 
     { 
      string getSeatNumber = listBox1.SelectedItem.ToString();//Tar första bokstaven i den markerade strängen i listboxen och gör om till index. 
      int seatNumber = int.Parse(getSeatNumber.Substring(0, 1)); 

      var result = MessageBox.Show(string.Format("Do you wish to cancel reservation? "), "Seat registered", MessageBoxButtons.YesNo, MessageBoxIcon.None); 
      if (result == DialogResult.Yes) 
      { 
       double amount = seatMngr.GetPaidPrice(seatNumber); 
       MoneyBackWhenCancelOrOverwrite(amount); 
       seatMngr.CancelSeat(seatNumber); 
       numOfReservedSeats--; 
      } 
      else { } 
     } 
     UpdateGUI(); 
    } 



    private void UpdateGUI() 
    { 
     labelVacant.Text = (totalNumOfSeats - numOfReservedSeats).ToString();//Visar antal ledig platser. 
     labelReserved.Text = numOfReservedSeats.ToString();//Visar antal reserverade platser. 
     labelRevenue.Text = revenue.ToString();//Visar intäkter. 
     labelSeats.Text = totalNumOfSeats.ToString();//Visar totalt antal platser. Värdet är konstant så det kan inte ändras. 
     DisplayOptions choice = (DisplayOptions)comboBox1.SelectedIndex; 

     string[] strSeatInfoStrings; 


     //seatMngr = new SeatManager(totalNumOfSeats); 

     int display = seatMngr.GetSeatInfoStrings(choice, out strSeatInfoStrings); 
     listBox1.Items.Clear(); 
     if (strSeatInfoStrings == null) 
     { 
      listBox1.Items.Add("No seats where found"); 
     } 
     else 
     { 
      listBox1.Items.AddRange(strSeatInfoStrings); 
     } 
    } 
+1

當你刪除該行時,你得到的錯誤是什麼? – Tudor

+0

nullreferenceexception was unledled – user1051477

回答

1

如果你有一個參考指向內存中的對象,然後將它分配一個新的實例,它以前指向的對象是「迷失」(提供有它不再引用),並最終收集垃圾。這就是爲什麼當您在UpdateGUI()內創建新實例時,您將丟失先前填充的所有數據。

如果您計劃在方法調用之間維護狀態,那麼正確的版本顯然沒有那個新的實例化。如果刪除該行,您得到的編譯器錯誤是什麼?

編輯:當你聲明seatMngr嘗試也使實例化和從構造中刪除:

private SeatManager seatMng = new SeatManager(totalNumOfSeats); 
+0

nullreferenceexception was unhandled – user1051477

+0

看看編輯是否有幫助。 – Tudor

+0

解決! Sweeeeet! Sweeeeeet!謝啦! 我很好奇,爲什麼它工作?爲什麼我會在構造函數中實例化對象時出錯? – user1051477

0

您需要發佈的代碼爲您SeatManager類或這將是很難知道什麼正在進行。目前我目前沒有看到問題,除非當前被註釋掉的行:

//seatMngr = new SeatManager(totalNumofSeats); 

被取消註釋。

+0

nullreferenceexception未處理 – user1051477

相關問題