Click here to Skip to main content
15,881,876 members
Please Sign up or sign in to vote.
2.00/5 (2 votes)
See more:
I'm having some problem with this method of mine. Somehow, I doesn't create or doesn't accept the created object (animal). It seems it only return null.

C#
public Animal GetSetAnimalInfo(string name, double age, CategoryType cat, object animalType, GenderType gender, string extra)
        {
            Animal animalObj = null;

            switch (cat)
            {
                case CategoryType.Bird:
                    Bird.BirdSpecies birdSpecie = (Bird.BirdSpecies)Enum.Parse(typeof(Bird.BirdSpecies), animalType.ToString());
                    animalObj = Bird.BirdFactory.CreateBird(birdSpecie); //late binding
                    break;

                case CategoryType.Insect:
                    Insect.InsectSpecies insectSpecie = (Insect.InsectSpecies)Enum.Parse(typeof(Insect.InsectSpecies), animalType.ToString());
                    animalObj = Insect.InsectFactory.CreateInsect(insectSpecie); //late binding
                    break;

                case CategoryType.Mammal:
                    Mammal.MammalSpecies mammalSpecie = (Mammal.MammalSpecies)Enum.Parse(typeof(Mammal.MammalSpecies), animalType.ToString());
                    animalObj = Mammal.MammalFactory.CreateMammal(mammalSpecie);
                    break;

                case CategoryType.Marine:
                    Marine.MarineSpecies marineSpecie = (Marine.MarineSpecies)Enum.Parse(typeof(Marine.MarineSpecies), animalType.ToString());
                    animalObj = Marine.MarineFactory.CreateMarine(marineSpecie);
                    break;

                case CategoryType.Reptile:
                    Reptile.ReptileSpecies reptileSpecie = (Reptile.ReptileSpecies)Enum.Parse(typeof(Reptile.ReptileSpecies), animalType.ToString());
                    animalObj = Reptile.ReptileFactory.CreateReptile(reptileSpecie);
                    break;
            }


            if (animalObj != null)
            {
                System.Windows.Forms.MessageBox.Show(animalType.ToString());
            }

            if (!InputUtility.IsLettersOnly(name))
            {
                string message = string.Format("Animal could not be registered because the name input was not correct.") + Environment.NewLine;

                throw new InvalidInputException(message);
            }
            else
            {
                animalObj.Name = name;
            }

            animalObj.ID = GenerateID(animalObj);

            if (!InputUtility.IsNumeric(age))
            {
                string message = string.Format("Animal could not be registered because the age input was not correct." + Environment.NewLine);

                throw new InvalidInputException(message);
            }
            else
            {
                animalObj.Age = age;
            }

            animalObj.Gender = gender;

            animalObj.ExtraAnimalInfo = extra;

            AddToList(animalObj);

            return animalObj;
        }


This is the second method, which is being used for the GUI whereas the first one handles the data, and creation of objects. However, as mentioned above, somehow the first method returns null

C#
private Animal AddAnimal()
        {
            Animal animalObj = null;
            try
            {
                animalManager.GetSetAnimalInfo( txtName.Text,
                                                Convert.ToDouble(txtAge.Text),
                                                (CategoryType)lstCategory.SelectedIndex,
                                                lstAnimalType.SelectedValue,
                                                (GenderType)lstGender.SelectedIndex,
                                                txtSpecialInput.Text);
            }
            catch (Exception ex) { MessageBox.Show(ex.Message); }

            if (animalObj != null)
            {
                try
                {
                    ListViewItem lvi = new ListViewItem(animalObj.Name);
                    lvi.SubItems.Add(animalObj.ID);
                    lvi.SubItems.Add(animalObj.Age.ToString());
                    lvi.SubItems.Add(animalObj.Gender.ToString());
                    lvi.SubItems.Add(animalObj.Category.ToString());
                    lstVRegisteredAnimals.Items.Add(lvi);

                }


                catch (FormatException ex) { MessageBox.Show(ex.Message); }
            }
            return animalObj;
        }
Posted
Comments
Sergey Alexandrovich Kryukov 4-Mar-13 19:06pm    
Can I unsee it? :-)
—SA

First, I agree that you are no using OOP, but let's focus on your problem.

You do:

Animal animalObj = null;


But you never do:
animalObj = something...


I think your animalManager.GetSetAnimalInfo should look more like:
animalObj = animalManager.GetSetAnimalInfo.

After all, your animalManager is returning an object that is lost, and then you are reading the animalObj variable.

That was the part 1. Simple solving your problem about animal being null.

But about the switch.
Instead of an enum (CategoryType) and a switch (over the cat variable) you could have a CategoryDelegate (to say that it is a categorytype, but that executes some code), an ICategoryType or something.
Then, each value of the switch is a new entire type, which implements a method (like CreateValue), without requiring a switch.

If you need help with that, I could give real examples... now I am simple trying to answer it fast.
 
Share this answer
 
Please do, yourself a big favor, stop all of this activity. A switch statement by the type is something directly opposite to OOP, a total abuse. Actually, roughly speaking, the main point of OOP was to avoid such things.

Nothing can help you to fix your code, just because the whole idea is wrong. It just makes no sense. Also, I don't see a reason to explain you how OOP works. Read anything explaining OOP; and I hope you will see what to do. Or not. :-(

[EDIT]

OK, a hint: whatever you have under each case should be a virtual method overridden in each concrete (non-abstract) class. Then some method using it should be one line: a call to the same method of an abstract class, as a compile-time type. As a run-time will be some concrete type, the call will be dispatched to one of the overridden methods, through late binding.

If you already using the term "late binding", use late binding.
As one Easter proverb say, "Saying "halva-halva" won't make your mouth sweet". :-)

—SA
 
Share this answer
 
v2
Comments
leprechauny 4-Mar-13 19:21pm    
Well, this is one of the methods that are being called under one of the cases. I don't see why you don't qualify it as late binding?

public static Bird CreateBird(BirdSpecies Species)
{
Bird animalObj = null; //Unknown at this time

//Late binding
switch (Species)
{
case BirdSpecies.Eagle:
animalObj = new Eagle();
break;

case BirdSpecies.Pelican:
animalObj = new Pelican();
break;

default:
Debug.Assert(false, "To be filled.");
break;
}

//Sets category
animalObj.Category = CategoryType.Bird;

//Returns the created object
return animalObj;
}
Sergey Alexandrovich Kryukov 4-Mar-13 19:31pm    
All wrong again. Forgot all your cases, finally! Makes no sense at all...
—SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900