Kevin.A
Kevin.A

Reputation: 77

Cannot convert System.String to class type

I'm working with Polymorphism and I've run into a problem.

What I want to do is to call Animal class method GetEaterType() when list item is selected but I can't convert the animal class to Resultlst.SelectedItem; This is how I tried:

private void Resultlst_SelectedIndexChanged(object sender, EventArgs e)
        {
            Animal theanimal = (Animal) Resultlst.SelectedItem;
            // EaterTypetxt.Text = theanimal.GetEaterType().ToString();
        }

When I select an item on the list, I get error

"Failed to convert an object of type System.String the type Assign_1.Animal"

UPDATE: How I populate the Resultlst with data

 private void UpdateResults()
        {
            Resultlst.Items.Clear();  //Erase current list
            //Get one elemnet at a time from manager, and call its 
            //ToString method for info - send to listbox
            for (int index = 0; index < animalmgr.ElementCount; index++)
            {
                Animal animal = animalmgr.GetElementAtPosition(index);

                //Adds to the list.
               Resultlst.Items.Add(animal.ToString());

            }

Upvotes: 0

Views: 7422

Answers (1)

Grant Winney
Grant Winney

Reputation: 66459

Don't call ToString() on your Animal when you add it to the list.

Use the DisplayMember property on the ListBox to specify which property of the Animal class should be displayed to the user.

for (int index = 0; index < animalmgr.ElementCount; index++)
{
    Animal animal = animalmgr.GetElementAtPosition(index);

    Resultlst.Items.Add(animal);   // add the Animal instance; don't call ToString()
}

Resultlst.DisplayMember = "Name";  // whatever property of your class is appropriate

Now you can cast the SelectedItem property to an Animal.

private void Resultlst_SelectedIndexChanged(object sender, EventArgs e)
{
    Animal theanimal = (Animal)Resultlst.SelectedItem;

    EaterTypetxt.Text = theanimal.GetEaterType().ToString();
}

Since you've got multiple properties you'd like to display (which is why you're using ToString() in the first place), you could add a property to your class with just a "getter", and reference that:

public class Animal
{
    public string Name { get; set; }
    public Color Color { get; set; }

    public string Description
    {
        get { return string.Format("{0} {1}", Color.Name, Name); }  // Red Dog, Purple Unicorn
    }
}

Resultlst.DisplayMember = "Description";

Addendum.. if you want to make the Description property overridable in derived classes, just make it virtual and override it when you want to:

public class Animal
{
    public string Name { get; set; }
    public Color Color { get; set; }

    public virtual string Description
    {
        get { return string.Format("{0} {1}", Color.Name, Name); }
    }
}

public class Dog : Animal
{
    public override string Description
    {
        get { return base.Description; }
    }
}

public class Cat : Animal
{
    public override string Description
    {
        get { return "I'm a cat. I'm special."; }
    }
}

Upvotes: 3

Related Questions