【问题标题】:Null reference when trying to cast listbox.selecteditem?尝试投射 listbox.selecteditem 时出现空引用?
【发布时间】:2016-09-19 15:11:19
【问题描述】:

所以为了学校作业,我必须建造一个动物收容所,

有两个对象:猫和狗,对象的每个新实例都被添加到对象列表中,如下所示:

    public Cat Cat { get; private set; }
    public Dog Dog { get; private set; }
    public List<Dog> Dogs = new List<Dog>();
    public List<Cat> Cats = new List<Cat>();

    public void NewCat(string name, Gender gender, string badHabits)
    {
        this.Cat = new Cat(name, gender, badHabits);
        Cats.Add(this.Cat);

    }

    public void NewDog(string name, Gender gender)
    {
        this.Dog = new Dog(name, gender);
        Dogs.Add(this.Dog);
    }  

使用更新方法,两个列表都被添加到列表框中,如下所示:

  private void Update()
    {
            lbAnimals.Items.Clear();
            lbAnimals.Items.Clear();
            foreach (Cat c in reservations.Cats)
        {
            lbAnimals.Items.Add(c.ToString());
        }
        foreach (Dog d in reservations.Dogs)
        {
            lbAnimals.Items.Add(d.ToString());
        }
    } 

最后我需要将列表框中的选定对象转换为 Dog 对象或 cat 对象,这就是为狗做的:

 private void btnReserveDog_Click(object sender, EventArgs e)
    {
        if (this.reservations.Dog != null)
        { 
            var d=  lbAnimals.SelectedItem as Dog; 
                d.Reserve(txtReservor.Text); 
                this.btnReserveDog.Enabled = false;
            Update();
        }
    } 

无论我尝试什么,当我转换对象时它返回一个空引用,我不知道为什么,任何帮助将不胜感激!

【问题讨论】:

  • 因为您在列表框中添加字符串作为元素而不是 Dog
  • 你有我应该如何添加它的例子吗?
  • 你必须创建一个基类Animal,然后从它继承Cat和Dog,然后创建一个包含CatDogList&lt;Animal&gt;作为Animal,然后绑定包含 lbAnimals 的列表,例如 lbAnimals.DataSource=animals

标签: c# .net wpf visual-studio listbox


【解决方案1】:

在列表框中显示对象的最佳方式不是转换为字符串并返回,而是因为对象具有字符串属性,所以它应该显示在列表框中。因此,请尝试改用列表框的 DisplayMember 属性。所以试试这个

LbAnimals.DisplayMember = "name"; // this sets tge property of the object that would be displayed to name.

private void Update()
{
        lbAnimals.Items.Clear();
        lbAnimals.Items.Clear();
        foreach (Cat c in reservations.Cats)
    {
        lbAnimals.Items.Add(c);
    }
    foreach (Dog d in reservations.Dogs)
    {
        lbAnimals.Items.Add(d);
    }
} 

        private void btnReserveDog_Click(object sender, EventArgs e)
           { 
              if (this.reservations.Dog != null)
            { 
                //you also missed a null check here, this might raise an exception if no item is selected in the listbox
           If ( lbAnimals.SelectedItem !=null)
               {
                 Dog  d=  lbAnimals.SelectedItem as Dog; 
                d.Reserve(txtReservor.Text); 
                this.btnReserveDog.Enabled = false;
                Update();
               }
           }
        } 

另一个问题是您将Dog 和Cat 对象都添加到同一个列表框,因此当您选择一只猫并尝试将其强制转换为一只狗时,您也会得到一个空引用异常。因此,您可能希望在转换之前使用 GetType() 方法检查类型。

【讨论】:

    【解决方案2】:

    ListBox 的 items 集合将接受任何类型的对象。您当前正在将您的对象从CatDog 转换为string,然后再添加,所以当然当您使用as 并尝试将string 转换回Dog 时,它会失败。 Dog 不是 string,这意味着您得到 null 作为结果(这就是 as 在转换失败时所做的)。

    您需要做的就是删除.ToString()。即:

    private void Update()
    {
        lbAnimals.Items.Clear();
        lbAnimals.Items.Clear();
        foreach (Cat c in reservations.Cats)
        {
            lbAnimals.Items.Add(c);
        }
        foreach (Dog d in reservations.Dogs)
        {
            lbAnimals.Items.Add(d);
        }
    }
    

    然后,当您处理集合中的Dog 元素时,您将在使用as 时获得Dog 实例。

    当然,对于Cat 元素,结果将是null。您仍然需要确保处理 null 值(当它是 Cat 时不要尝试转换为 Dog,反之亦然,或者检查 null 结果)。

    【讨论】:

    • 这竟然是我的解决方案!老实说,当我发现这就是我整个星期天都在做的事情时,我觉得有点愚蠢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-01
    • 1970-01-01
    • 2014-07-11
    • 2011-02-02
    相关资源
    最近更新 更多