5

这可能看起来有点“家庭作业”和/或微不足道,但它是出于真正的商业目的;这只是我能想到的最简单的方法来解释我在概念上试图做什么。

假设我有一个 Animal 类和一些其他类(Bird、Cat、Kangaroo)。这些中的每一个都继承自 Animal。

动物可能看起来像这样:

public class Animal
{
    public Animal()
    {

    }

    public string Name { get; set; }
    public string AnimalType { get; set; }
    public List<Animal> Friends { get; set; }
}

袋鼠可能看起来像这样:

public class Kangaroo : Animal
{
    public Kangaroo()
    {

    }

    public int TailLengthInches { get; set; }
}

假设袋鼠有两个朋友,一只鸟和一只猫。我怎样才能将这些添加到“动物”朋友列表中(作为动物类型),但保留访问派生类属性的能力?(例如,我仍然需要能够使用特定于动物类型的属性,例如鸟类的 FeatherColor,即使它们将被视为只是“动物”。

我尝试这样做的原因是,当我后来得到动物的“朋友”列表时,我知道朋友是什么类型的动物是至关重要的。根据动物类型(无论是鸟、猫等),我想做一些不同的事情(实际上,在 ASP.NET 页面上显示不同的模板,但我不需要专门的帮助)。

我想这可以归结为...如果我有一个 Animal 列表,我怎么知道列表中每个对象的派生类型是什么,所以我可以将它们转换回它们的派生类型或做其他事情这使我能够获得每个派生类型上特定的不同属性?

谢谢!

4

5 回答 5

8

您可以使用 LINQ 过滤您要查找的类型

animals.Friends = new List<Animal> { new Kangaroo(), new Bird() };
foreach ( var kangaroo in animals.Friends.OfType<Kangaroo>()) {
  kangaroo.Hop();
}
于 2010-01-15T21:17:04.920 回答
2

尝试投射它:

var friendBird = friend as Bird;
if (friendBird != null)
{
    // It's a bird, so do something with it
)
于 2010-01-15T21:09:32.923 回答
2

您可以使用typeof来获取实际类型,或使用isoras运算符进行测试并选择强制转换:

foreach (Animal a in Friends)
{
  Kangaroo k = a as Kangaroo;
  if (a != null)
  {
    // it's a kangaroo
    k.JumpAround();
  }
  Ostrich o = a as Ostrich;
  if (o != null)
  {
    o.StickHeadInSand();
  }
}

(我在这里没有使用else子句,如果您针对可能在层次结构中的类型进行测试,这可能会导致错误,例如,如果您同时拥有 Kangaroo 和 Marsupial 子句,您可能不希望两者都被执行!)

您也可以使用操作符来执行此is操作,它看起来更好,但会让 FxCop 哭泣:

foreach (Animal a in Friends)
{
  if (a is Kangaroo)
  {
    ((Kangaroo)a).JumpAround();
  }
}

一般来说,顺便说一句,您可能希望寻找机会放置一个虚拟方法Animal并以多态方式实现该方法,而不是拥有导致与一组特定派生类的脆弱耦合的怪物 if 语句。

于 2010-01-15T21:11:57.623 回答
0

使用“是”关键字。

如果(动物是鸟)...

于 2010-01-15T21:12:40.483 回答
0
animals.Friends = new List<Animal> { new Kangaroo(), new Bird() };
foreach (Animal animal in animals.Friends)
{
if (animal is Kangaroo)
Console.WriteLine("Kangaroo");
else if (animal is Bird)
Console.WriteLine("Bird");
}
于 2010-01-15T21:15:02.417 回答