複雑なカードゲームを作っています。Card
だから私は、このゲームに固有のいくつかの属性を持つクラスを持っていますList<Effect> effects
。クラスには、その効果を読みやすい英語に解析するための基本的なメソッドもいくつかGetParsedEffects()
あります。これは、リストを処理し、それらを文字列に解析します。
public class Card {
public List<Effect> effects;
public string GetParsedEffects() {
foreach(Effect e in effects)
//formatting stuff
}
}
今、私はあなたがカードの同一の双子を作成する非常に特殊な効果を作成したいと決めました. 一卵性双生児とは、他のカードと常に同じ値を持つカードを意味し、どちらかが値を更新すると、両方が影響を受けます。これは、まったく同じカードの 2 つのインスタンスを持っているようなものです (ただし、完全に同じにすることはできません。そのうちの 1 つをプレイするときは、両方が捨て札に行かないように、それがどちらであるかを知る必要があります)。
継承を使用してこれを実行しようとしました。そこで、子クラスを作成しました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();
}
適切な例: リストに 1 つの効果を持つ Concentrate という名前のカードがあります。元の設定が Concentrate の TwinCard を持っています。デバッグ モード (Visual Studio) では、「effects」という名前の 2 つのフィールドが表示されます。1 つは空で、もう 1 つは Concentrate で参照されている効果があります。TwinCard で GetParsedEffects() を入力すると、リストに効果が 0 として表示されます。おそらく、効果フィールドの 1 つを使用しますが、他のフィールドは使用しません。
これが C# のバグである場合、どうすれば回避できますか? これが予期される動作である場合、そうでなければどのように設計しますか? 私が見る唯一の他のオプションは、すべての属性の変更に対してイベントとリスナーを実装し、それらのリスナーに応じて TwinCard に独自の値を更新させることです。しかし、それはリスナーの巨大なウェブです。