这可能看起来像“家庭作业”和/或微不足道,但它是出于真正的商业目的;这是我能想到解释我在概念上试图做的最简单的方法。
假设我有一个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页面上,其实,但我并不需要提供帮助的具体)。
我想它归结为这个......如果我有动物的名单了,我怎么知道是什么派生类型是为每个在列表中的对象,所以我可以投他们回到自己的派生类型或做一些其他的事情,让我可以到达每个派生类型的特定的不同属性?
谢谢!
答案 0 :(得分:8)
您可以使用LINQ过滤您正在寻找的类型
animals.Friends = new List<Animal> { new Kangaroo(), new Bird() };
foreach ( var kangaroo in animals.Friends.OfType<Kangaroo>()) {
kangaroo.Hop();
}
答案 1 :(得分:2)
尝试投射它:
var friendBird = friend as Bird;
if (friendBird != null)
{
// It's a bird, so do something with it
)
答案 2 :(得分:1)
您可以使用typeof
获取实际类型,或使用is
或as
运算符来测试和选择投射:
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语句导致与特定方法的脆弱耦合派生类的集合。
答案 3 :(得分:0)
使用'is'关键字。
如果(动物是鸟) ...
答案 4 :(得分: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");
}