2011-11-23 89 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

相关问题