我正在制作一个复杂的纸牌游戏。所以我有一个类Card
,它有一些特定于这个游戏的属性,例如List<Effect> effects
. 该类还有一些基本方法可以将其效果解析为可读的英语,GetParsedEffects()
这些方法通过列表工作并将它们解析为字符串。
public class Card {
public List<Effect> effects;
public string GetParsedEffects() {
foreach(Effect e in effects)
//formatting stuff
}
}
现在我决定要创建一个非常特殊的效果,您可以在其中创建一张卡片的同卵双胞胎。当我说同卵双胞胎时,我的意思是一张卡片总是与另一张卡片具有相同的值,并且当它们中的任何一个更新值时,两者都会受到影响。这就像有两张同一张牌(但它们不可能完全相同,因为当你打出其中一张时,我需要知道是哪一张,这样它们就不会都进入弃牌堆。)
我试图通过使用继承来做到这一点。所以我创建了一个子类TwinCard : Card
。TwinCard 有一个附加属性 ,Card original
并在所有属性上使用new
关键字,以便它们获取和设置原始卡的属性而不是它自己的属性。所以基本上,你有一张原始卡,然后是只反映原始卡的双卡,对双卡的更改会影响原始卡。由于两者都Card
作为类共享,因此所有方法都可以使用它们。
public class TwinCard : Card {
public Card original;
public new List<Effect> effects { get { return original.effects;} set { original.effects = value; } }
public TwinCard(Card original) {
this.original = original;
}
}
我对自己很满意。
直到我试图跟GetParsedEffects()
注所有手牌,包括 TwinCard。由于这是一个基类方法,它似乎使用基类字段effects
而不是用关键字标记的 TwinCard 版本new
。所以它试图使用所谓隐藏effects
的基类,而不是new List<Effect> effects
.
我的印象是new
关键字意味着任何和所有调用都将交换new
版本,但看起来情况并非如此。我做错了什么,还是我误解了它的new
工作原理?
我认为这与我遍历手牌的方式有关,将卡片定义为Card
;
foreach(Card c in hand) {
c.GetParsedEffect();
}
举个例子:我有一张名为 Concentrate 的卡片,它的列表中有 1 个效果。我有一张 TwinCard,其原始设置为 Concentrate。在调试模式 (Visual Studio) 中,我可以看到 2 个名为“效果”的字段,一个为空,另一个具有 Concentrate 中引用的效果。当我在 TwinCard 上输入 GetParsedEffects() 时,它在列表中显示效果为 0,据说它使用了一个效果字段,而不是另一个。
如果这是一个 C# 错误,我将如何解决它?如果这是预期的行为,我将如何设计它?我看到的唯一其他选择是为每个属性的更改实现事件和侦听器,并让 TwinCard 根据这些侦听器更新自己的值。但这是一个庞大的听众网络。