C#Polymorphism - 访问不在父级中的子类的属性

Div*_*Vox 9 c# polymorphism

我遇到了能够调用子类特有的函数/属性的问题.我想知道是否有办法做类似以下的事情:

public class Creature
{
   public int HealthPoints {get; set;}
   public string Name {get; set;}
   public int AttackValue {get; set;}

   public Creature();
}

public class Magical : Creature
{
   public int Mana {get; set;}
}
Run Code Online (Sandbox Code Playgroud)

因此,在这个基本的例子中,我有一个生物列表,并且需要能够从任何给定的魔法生物的法力属性中调用.

sta*_*ica 18

简短的回答:

正如您在其他答案中肯定看到的那样,您可以访问Mana魔法生物的属性,如下所示:

foreach (Creature creature in creatures)
{
    if (creature is Magical magical)
    {
        // ... do something with 'magical.Mana' here...
    }
}
Run Code Online (Sandbox Code Playgroud)

更进一步:

既然我们已经在谈论多态性,你应该知道这if (x is SomeType) { .. }可能是代码味道.假设你确实有一个foreach循环来处理你所有的生物.最好在基类中创建一个虚方法,并在该虚方法中执行你在foreach循环内所做的任何事情.然后,您将覆盖您的Magical类中的方法,从而摆脱该if语句.

我们举个例子.让我们说,你的所有生物都会受到打击并失去一些能量.正常生物失去健康点,而魔法生物失去法力值:

public partial class Creature   // rest of your class is omitted in this example
{
    public virtual void TakeHit()
    {
        // whatever you had in your original foreach loop, e.g.:
        HealthPoints--;
    }
}

public partial class Magical : Creature
{
    public override void TakeHit()
    {
        // ... any special processing for Magical creatures goes here, e.g.:
        Mana--;
        // (you could also call 'base.TakeHit()' in this method.)
    }
}
Run Code Online (Sandbox Code Playgroud)

您的原始foreach循环现在变得更加简单:

foreach (Creature creature in creatures)
{                        // note: no more if statement -- The virtual method
    creature.TakeHit();  // invocation now takes care of distinguising
}                        // different (sub-)types of Creatures!
Run Code Online (Sandbox Code Playgroud)

我想向你推荐一个关于这个主题的非常好的演示:条件和多态.


jas*_*son 11

因此,在这个基本的例子中,我有一个生物列表,并且需要能够从任何给定的魔法生物的法力属性中调用.

是的,这是可能的.用途Enumerable.OfType<T>:

IEnumerable<Creature> creatures = new List<Creature>();
// populate creatures
var magicalCreatures = creatures.OfType<Magical>();
foreach(var magicalCreature in magicalCreatures) {
    Console.WriteLine(magicalCreature.Mana);
}
Run Code Online (Sandbox Code Playgroud)


Ree*_*sey 5

此时你需要转换为"魔法".例如:

Creature aCreature = GetMyCreature();
Magical asMagical = aCreature as Magical; // Using "as" operator..
if (asMagical != null)
    Console.WriteLine(asMagical.Mana);
Run Code Online (Sandbox Code Playgroud)