2015-12-16 3 views
-2

Я новичок, и я кодирую легкую программу Windows Form в C# (ну не так просто для меня, но для опытного программиста), которая работает так: форма (класс ContactForm) получает вход (имя, имя, адрес, адрес электронной почты и телефон n) от пользователя и сохраняет его в переменных класса Contact через свойства. Класс Contact вызывает свойства и методы из других трех классов (адрес, адрес электронной почты и телефон) для хранения и проверки ввода пользователя. Класс Contact также содержит переопределяющий метод ToString, который форматирует переменные, содержащие вход пользователя в строку. На этом этапе я попытался вызвать этот метод ToString с помощью ContactForm и отобразить строку в MessageBox, и она отлично работала. Но затем я попытался вызвать метод с другим классом Customer, который имеет объект класса Contact, и это было катастрофой. Компилятор сохраняет соответствие NullReferenceException для объекта класса Contact (m_contact), который говорит null. Вот код:Поймите, почему NullReferenceException был необработанным?

public class Customer 
{ 
    private Contact m_contact; 
    private int m_ID; 

    public Customer() 
    { 

    }public Customer(Contact contactIn) 
    { 

    }public Customer(Contact contactIn, int id) 
    { 
     if (m_contact != null) 
     { 
      m_contact = new Contact(); 
      m_contact = contactIn; 
     } 
     m_ID = id; 
    }public Contact ContactData 
    { 
     get { return m_contact; } 
     set { 
      if (value != null) 
       m_contact = value; } 
    }public int ID 
    { 
     get { return m_ID; } 
     set { m_ID = value; } 
    } 
    public override string ToString() 
    { 
     string strOut = string.Empty; 
     **if ((!string.IsNullOrEmpty(m_contact.ToString())) && (m_contact != null) && (m_contact.Validate()))** 
     { 
      strOut = m_contact.ToString(); 
     } 
     else 
      strOut = null; 
     return strOut; 
    } 
} 

} Строки в звездочках является тот, где находится ошибка. И это один метод m_contact.Validate:

public bool Validate() 
    { 
     bool ok = false; 
     if (!string.IsNullOrEmpty(m_firstName) && (!string.IsNullOrEmpty(m_lastName)) && m_address.CheckData() && m_email.CheckEmail() && m_phone.CheckPhone()) 
      ok = true; 
     else 
      ok = false; 
     return ok; 
    } 

Просто для большей ясности, это метод email.CheckEmail, но эти методы проверки выше, безусловно, не проблема:

public bool CheckEmail() 
    { 
     bool ok = false; 
     if ((!string.IsNullOrEmpty(m_personal)) || (!string.IsNullOrEmpty(m_work))) 
      ok = true; 
     else 
      ok = false; 
     return ok; 
    } 

И это код из класса ContactForm, который отображает метод ToString Контактного класса с абсолютно никаких проблем:

public partial class ContactForm : Form 
{ 
    private Contact m_contact; 
    private bool m_closeForm; 
    public ContactForm(string title) 
    { 
     InitializeComponent(); 
     m_contact = new Contact(); 
     this.Text = title; 
     InitializeGUI(); 
    }public Contact ContactData 
    { 
     get { return m_contact; } 
     set 
     { 
      if (value != null) 
      m_contact = value; 
     } 
    }private void InitializeGUI() 
    { 
     txtFirstName.Text = string.Empty; 
     txtLastName.Text = string.Empty; 
     txtHomePhone.Text = string.Empty; 
     txtCellPhone.Text = string.Empty; 
     txtEMailBus.Text = string.Empty; 
     txtEMailPr.Text = string.Empty; 
     txtStreet.Text = string.Empty; 
     txtCity.Text = string.Empty; 
     txtZip.Text = string.Empty; 
     FillCountryComboBox(); 
     cmbCountry.SelectedIndex = (int)Countries.Sverige; 
     m_closeForm = true; 
    }private void FillCountryComboBox() 
    { 
     cmbCountry.Items.AddRange(Enum.GetNames(typeof(Countries))); 
    } 

    private void MainForm_FormClosing(object sender, FormClosingEventArgs e) 
    { 
     if (m_closeForm) 
      e.Cancel = false; 
     else 
      e.Cancel = true; 
    }public bool ReadInput() 
    { 
     m_contact.FirstName = txtFirstName.Text; 
     m_contact.LastName = txtLastName.Text; 
     m_contact.AddressData = ReadAddress(); 
     m_contact.EmailData = ReadEmail(); 
     m_contact.PhoneData = ReadPhone(); 

     bool ok = m_contact.Validate(); 
     if (ok) 
     { 
      return true; 
     } 
     else 
     { 
      MessageBox.Show("Please provide at least your firstname, lastname, phone number, email address, city and country"); 
      return false; 
     } 
    }private Address ReadAddress() 
    { 
     Address m_address = new Address(); 

     m_address.Street = txtStreet.Text; 
     m_address.City = txtCity.Text; 
     m_address.ZipCode = txtZip.Text; 
     m_address.Country = (Countries)cmbCountry.SelectedIndex; 
     return m_address; 
    }private Email ReadEmail() 
    { 
     Email m_email = new Email(); 

     m_email.Work = txtEMailBus.Text; 
     m_email.Personal = txtEMailPr.Text; 
     return m_email; 
    }private Phone ReadPhone() 
    { 
     Phone m_phone = new Phone(); 

     m_phone.Home = txtHomePhone.Text; 
     m_phone.Other = txtCellPhone.Text; 
     return m_phone; 
    } 

    private void btnOK_Click(object sender, EventArgs e) 
    { 
     if (ReadInput()) 
     { 
      UpdateGUI(); 
      m_closeForm = true; 
      this.Close(); 
     } 
     else 
      m_closeForm = false; 
    }public void UpdateGUI() 
    { 
     string strOut = m_contact.ToString(); 
     MessageBox.Show(strOut); 
    } 
    } 
} 

} Кроме того, клиент T Метод oString вызывается MainForm для отображения сообщения в MessageBox. Это метод, в MainForm:

private void btnAdd_Click(object sender, EventArgs e) 
    { 
     ContactForm contForm = new ContactForm("Add a new customer"); 
     Customer cust = new Customer(); 
     int index = lstResults.SelectedIndex; 

     if (index != -1) 
      contForm.ContactData = customerMngr.GetCustomer(index).ContactData; 

     if (contForm.ShowDialog() == DialogResult.OK) 
     { 
      lstResults.Items.Clear(); 


      if (contForm.ReadInput() && (!String.IsNullOrEmpty(cust.ToString()) && (cust != null))) 
      { 
       MessageBox.Show(cust.ToString()); 
      } 
     } 

Почему m_contact в классе нуль клиента, а не один в классе ContactForm? Извините за длину этого сообщения, мне очень трудно понять. Спасибо!

+2

В дополнение к дубликата ссылке выше, которая поможет в отладке, ваш вопрос, как он стоит, содержит довольно много кода, что делает его трудно посмотреть, что происходит. Чтобы помочь нам помочь, попробуйте уменьшить проблему до [MCVE] (http://stackoverflow.com/help/mcve). –

ответ

0

Прежде всего, вы должны проверить, если m_contact не является нулевым, а затем попробуйте метод вызова ToString на этом объекте. В противном случае вы получите исключение NullReferenceException, поскольку вы вызываете метод для нулевого объекта.

В основном, переписать

**if ((!string.IsNullOrEmpty(m_contact.ToString())) && (m_contact != null) && (m_contact.Validate()))** 
     { 
      strOut = m_contact.ToString(); 
     } 
     else 
      strOut = null; 

к:

if (m_contact != null && !string.IsNullOrEmpty(m_contact.ToString()) && m_contact.Validate()) 
{ 
    strOut = m_contact.ToString(); 
} 
else 
    strOut = null; 
+0

Благодарим за помощь. Ошибка исчезла! –

+0

Хотя этот ответ верен и отвечает на вопрос Astart.e, это ответ на дублирующий вопрос, который просто побуждает людей задавать повторяющиеся вопросы. Я думаю, что более полезно указать на уже обширный и ясный ответ на [Что такое исключение NullReferenceException и как его исправить?] (Http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception -and-how-do-i-fix-it) –

+0

@KevinВы правы, я сожалею о своей ошибке. В следующий раз я сначала начну искать двойственность. –