我遇到了能够调用子类特有的函数/属性的问题.我想知道是否有办法做类似以下的事情:
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)
此时你需要转换为"魔法".例如:
Creature aCreature = GetMyCreature();
Magical asMagical = aCreature as Magical; // Using "as" operator..
if (asMagical != null)
Console.WriteLine(asMagical.Mana);
Run Code Online (Sandbox Code Playgroud)