C#交叉方法问题,后期绑定 [英] C# cross-method issue, late-binding

查看:62
本文介绍了C#交叉方法问题,后期绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用这种方法时遇到了一些问题。不知何故,我没有创造或不接受创造的对象(动物)。它似乎只返回null。



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.

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;
        }





这是第二种方法,用于GUI,而第一种方法处理数据,创建对象。但是,如上所述,某种方式第一种方法返回null





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

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;
        }

推荐答案

首先,我同意你不使用OOP,但让我们专注于你的问题。



你这样做:



动物animalObj = null;





但你永远不会这样做:

animalObj =某事......





我认为你的animalManager.GetSetAnimalInfo应该更像:

animalObj = animalManager.GetSetAnimalInfo。



毕竟,你的animalManager返回一个丢失的对象,然后你正在读取animalObj变量。



那是第1部分。简单解决你关于动物的问题。



但关于开关。

而不是枚举(CategoryType)和开关(通过cat变量)你可以有一个CategoryDe​​legate(说它是一个categorytype,但执行一些代码),一个ICategoryType或者什么。

然后,每个值o如果开关是一个新的整个类型,它实现了一个方法(比如CreateValue),而不需要开关。



如果你需要帮助,我可以给真正的例子......现在我很简单,试图快速回答。
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.


请自己做一个大忙,停止所有这些活动。类型的switch语句是与OOP 直接相反的东西,完全滥用。实际上,粗略地说,OOP的主要观点是避免这样的事情。



没有什么可以帮助你修复代码,只是因为整个想法都是错的。这没有任何意义。另外,我没有理由向你解释OOP的工作原理。阅读任何解释OOP的内容;我希望你会看到该怎么做。或不。 :-(







好​​的,一个提示:无论你在每个案件下有什么应该是一个在每个具体(非抽象)类中重写的虚方法。然后使用它的一些方法应该是一行:调用抽象类的相同方法,作为编译时类型。由于运行时将是一些具体类型,调用将被调度到一个被覆盖的方法,通过后期绑定。



如果你已经使用了后期绑定一词,请使用后期绑定。

正如一句复活节谚语所说,说halva-halva不会让你的嘴巴变甜。: - )< br $>


-SA
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. :-(



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


这篇关于C#交叉方法问题,后期绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆