我们以下面的类为例:
基类:
public class Spell
{
public int castRange;
public Spell Copy()
{
Spell spell = new Spell();
spell.castRange = this.castRange;
return spell;
}
}
派生类:
public class ManaSpell : Spell
{
public int manaCost;
public new ManaSpell Copy()
{
ManaSpell spell = new ManaSpell();
spell.castRange = this.castRange;
spell.manaCost = this.manaCost;
return spell;
}
}
我不能为 Copy() 方法使用 virtual 和 override 因为它们有不同的返回类型,所以我使用新关键字。问题从下一节课开始:
public class Unit
{
public Spell spell;
public Unit(Spell spell)
{
// This will call the Copy method in the base class, even if the
// parameter is actually a ManaSpell
this.spell = spell.Copy();
// So instead I have to do a check first:
if (spell is ManaSpell)
{
ManaSpell manaSpell = spell as ManaSpell;
this.spell = manaSpell.Copy();
}
}
}
一切正常,但感觉这是一个非常低效的设计,尤其是如果我添加越来越多的 Spell 派生类,更不用说在基类中添加一个字段意味着更改复制方法在所有派生类中也是如此。
有更好的方法吗?
最佳答案
除非你有充分的理由隐藏(这就是new
所做的)你的Copy
- 基类的实现,你不应该 new
它。
看来您根本不需要它。您实际上想要复制一个 Spell
,而不管它的实际类型。因此,让实例解析对 Copy
的调用,这是通过通常的覆盖来完成的:
public class Spell
{
public int castRange;
public virtual Spell Copy()
{
Spell spell = new Spell();
spell.castRange = this.castRange;
return spell;
}
}
public class ManaSpell : Spell
{
public int manaCost;
public override Spell Copy()
{
ManaSpell spell = new ManaSpell();
spell.castRange = this.castRange;
spell.manaCost = this.manaCost;
return spell;
}
}
现在您可以在 Spell
的任何实例上调用 Copy
而无需区分实际类型:
this.Spell = spell.Copy()
如果您有基类实例,这将解析为 Spell
的新实例;如果您有派生类型的实例,则解析为 ManaSpell
。
关于c# - 如何正确地从派生类复制字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54331521/