2017-02-09 9 views
0

私はList<Character> citizensです。 市民が最も重要な様々な特性を持っている:基本クラス参照を子クラスにコピーするときに、問題がありますか? (ダウンキャスティング)

public string firstname; 
public Dictionary<Character, Relationship> relationships { get; set; } 
... 

市民は、物事になることができます彼らはを作成した後、Trader : Characterのように。
市民の私のリストでは、キャラクターのリファレンスをトレーダーに置き換えたいと思っています。

ダウンキャスティングに関する回答を読み、理解しています。

public Trader(Character c) 
{ 
    firstname = c.firstname; 
    relationships = c.relationships; 
    ...   
} 

をそして私は古い文字への参照を交換して、この派手な新しいトレーダーを使用したい:だから私は、コンストラクタのアプローチを行います

citizens.Remove(old); 
citizens.Add(fancyTrader); 

私に関するどのような関係辞書への参照ですこれは、古いCharacterオブジェクトが永遠にぶら下がってしまうだけではなく、メモリ内にこの男のコピーが2つあり、古いものがガベージコレクションされることはありませんか?

私はこれらの市民が何万人もいるので心配しています。

+1

この分類は、市民の代わりに市民の財産でもあります。クローンで型を変換すると、古くなった参照で作業することになります。 –

答えて

2

これを回避する1つの方法は、継承の代わりに合成を使用することです。 Characterの情報を複数の部分に抽象化することを検討してください。 Characterクラスは名前データと関係を保持し、Roleクラスは「ジョブ」を保持します。 TraderRoleのサブクラスとなり、彼らは複数を持つことができる場合Characterはその市民の役割(または役割のさえリストのためにそれのプロパティを持っているでしょう。

これはあなたに多くの柔軟性を与え、また、防止文字が役割を変えるときにあなたの参照が絡みつくのを避ける

+0

恐らくこれは答えかもしれません:-(私のコードベースのほとんどが 'Character'を使っているので、これは重要なアーキテクチャ上の変更です。 – LordYabo

0

はい、このシナリオではメモリリークが発生する可能性がありますが、あなた自身が後で解決するよう気をつけているなら、ダウンキャストとは関係ありません。

ダウンキャストの主な「落とし穴」は、実際にキャストしようとしていないタイプ(それは理想的ではない)にランタイムエラーです。あなたのアプローチでは、あなたはの浅いコピーと潜在的なバグを起こしていることを理解している必要があります。

私はプロファイラでしばらくプログラムを実行しますが、問題があるかどうかを確認するために参照数が増えていないことを確認してください。あなたのCitizenにオブジェクトをもはや必要としなくなったときにリレーションシップ辞書をクリーンアップする「Dispose」メソッドを持つと、そのような問題を解決するための長い道のりができます。

関連する問題