如何使用GetType访问C#中派生类的方法/属性?

时间:2011-01-04 18:07:03

标签: c# class inheritance abstract

我有两个派生类,Dog和Bird,它们派生自一个基类Animal。

Dog有一个属性Kennel,而Bird有一个属性Nest。

我想要一个方法(在一个单独的静态类中),它可以接收Animal类的一个实例,检查类型,然后调用其他方法,这些方法将Kennel或Nest作为参数传递给它们,例如: / p>

if (MyAnimal.GetType = Dog)
{MyKennelMethod(MyAnimal.Kennel)}
else if (MyAnimal.GetType = Bird)
{MyNestMethod(MyAnimal.Nest)}

我猜这不起作用。当你只有基类时,有没有办法访问派生类的属性?如果可能的话,我宁愿不要使用单独的抽象方法来混淆Dog和Bird类,因为我更喜欢使用单独的静态类来处理所有方法。我也希望它易于扩展,因此我可以拥有数百种来自Animal的新“动物”。

对于代码语法上的任何错误感到抱歉,我目前没有编辑器。

4 个答案:

答案 0 :(得分:4)

当然,没问题。

Dog dog = myAnimal as Dog;
Bird bird = myAnimal as Bird;
if (dog != null)
   KennelMethod(dog.Kennel);
else if (bird != null)
   NestMethod(bird.Nest);

但是,我建议首先避免这种情况。如果你有一个方法需要一个动物,但真的需要一只狗或一只鸟,那么听起来你真的想要两种方法,一种需要一只狗,一种需要一只鸟。

  

如果可能的话,我宁愿不用个别的抽象方法使狗和鸟类混乱。我也希望它易于扩展,因此我可以拥有数百种来自Animal的新“动物”。

你的要求有些矛盾;您不希望在类型代码本身中编码有关类型层次结构的信息,因此这些内容必须在类型层次结构之外,因此您有可伸缩性问题。

您是否考虑过使用访客模式?这是对对象的运行时类型进行虚拟分派的一种相当标准的方法,但是实际执行的代码存在于类外部。

答案 1 :(得分:3)

你总是可以施放动物物体。但我不建议以这种方式实现它,请阅读以下内容。

public static void DoSomething(Animal animal)
{
    if (animal is Dog)
    {
      MyKennelMethod((animal as Dog).Kennel);
    }
    else if (animal is Bird)
    {
      MyNestMethod((animal as Bird).Nest);
    }
}

这种方法打破了继承的目的。正确的方法是在父对象(动物)中公开一个公共属性。这是一个非常简单的例子。您可以为Home定义一个公共类型,每个子对象以不同的方式公开它:

public abstract class Animal
{
    public abstract string Home;
}

public class Dog : Animal
{
   public override string Home = "Kennel";
}

public class Bird : Animal
{
   public override string Home = "Nest";
}

答案 2 :(得分:2)

你必须施展:

void SomeMethod(Animal animal)
{
    var dog = animal as Dog;
    var bird = animal as Bird;

    if (dog != null)
    {
        // it's a dog - do whatever you want with the dog
    }

    if (bird != null)
    {
        // it's a bird - do whatever you want with the bird
    }
}

然而,这是一种代码味道。设计类可能有更好的方法,因此不需要这种类型的转换。例如,Animal可能会公开Home属性,该属性在Kennel时返回Dog,在Nest时返回Bird。或者,您的静态方法可能只需要Dog,然后重载需要Bird

答案 3 :(得分:0)

我认为Kennel,Nest和将它们作为params的方法有一些共同点,对吧?如果是这样,我建议接口:

interface SweetHome
{ 
    // members
}

class Dog: Animal
{
    public SweetHome Kennel { get; set; }
}

class Bird: Animal
{
    public SweetHome Nest { get; set; }
}

这可以满足您的需求。但我仍然认为方法应该位于派生自Animal的类中,而不是位于外部的某些静态类中。