次のクラス構造があるとします。
class Base {}
class DerivedA: Base {}
class DerivedB: Base {}
class Container
{
public List<Base> Items { get; }
}
アプリケーションがより多くの機能を開発するにつれて、派生オブジェクトのリストが時間の経過とともに大きくなります。私はやろうとしています:
Container container = ReturnsContainer();
foreach (var item in container.Items)
{
doStuff(item);
}
ここで、doStuff(item) は派生型によってオーバーロードされます。
void doStuff(DerivedA) {}
void doStuff(DerivedB) {}
コンパイラが「'Base' から 'DerivedA' に変換できません」および「最適なオーバーロードされたメソッドの一致 doStuff(DerivedA) には無効な引数があります」と言うため、これは機能しません。私が思いつくことができる最善のアプローチは次のとおりです。
Container container = ReturnsContainer();
foreach (var item in container.Items)
{
if (item is DerivedA)
{
doStuff((DerivedA)item);
}
else if (item is DerivedB)
{
doStuff((DerivedB)item);
}
}
これをよりきれいにする方法について何か考えはありますか?私の派生型は時間の経過とともに成長するだけなので、これを機能させ続けるには、構造に戻ってこの long if 構造に追加する必要があります。
派生型の数が増えると、container.Items.OfType<> ソリューションはパフォーマンス ヒットの増加 (および不必要な) につながると思います。
これには一般的なデリゲートを使用する必要がありますか? 単純なポリモーフィズムであるべきだと思われるものに対して、過度に複雑なソリューションのように思えます。
編集: さらに明確にするために、基本型と派生型の階層が別の API レイヤーにあり、変更できないとしましょう (最終クラス)。このソリューションは、既存の継承構造で機能する必要があり、Base オブジェクトと Derived オブジェクトを拡張することはできません。ただし、API レイヤーは時間の経過とともに新しい派生クラスを成長させることができます。