さて、これが状況です。私はFlexCollection<T>
クラスを持っています。その目的は、のいくつかの専門分野のリストを保持することFlexItem
です。したがって、次のようになります。
public class FlexCollection<T> where T : FlexItem, new()
{
public void Add(T item) { ... }
...
}
FlexItem
ジェネリッククラス自体ではありません。私が達成したかったFlexItem
のは、オブジェクトを含むコレクションへの参照をフィールドに保持する機能です。残念ながら、C#では、テンプレートクラスの「任意の」特殊化への参照を保持することはできません(Javaの場合のように)。最初は非ジェネリックインターフェイスを使用しようとしましIFlexCollection
たが、実際には各メソッドを2回実装する必要がありました。
public class FlexCollection<T> : IFlexCollection where T : FlexItem, new()
{
public void Add(T item) { ... } // to use in generic calls
public void Add(object item) { ... } // to use for calls from within FlexItem
...
}
それから、FlexItem自体をジェネリッククラスにできることを知りました。次に、スペシャライゼーションは、このスペシャライゼーションのオブジェクトのコレクションへの参照を保持できます(これは非常に論理的です)。したがって:
public class FlexItem<T> where T : FlexItem<T>, new()
{
public FlexCollection<T> ReferenceToParentCollection;
...
}
public class FlexCollection<T> where T : FlexItem<T>, new()
{
public void Add(T item) { ... }
...
}
今、私はいくつかのFlexItem<T>
専門分野と対応するコレクションを宣言することができます:
public class BasicItem : FlexItem<BasicItem> { public int A; }
public class BasicCollection : FlexCollection<BasicItem> { };
これらのクラスを拡張して追加のフィールドを保持しようとすると、問題が発生します。つまり、フィールドに加えてフィールドを保持するExtendedItem
クラスが必要でした:B
A
public class ExtendedItem : BasicItem { public int B; }
public class ExtendedCollection : FlexCollection<ExtendedItem> { };
そして、それExtendedItem
はのサブクラスでFlexItem<BasicItem>
あり、ではありませんFlexItem<ExtendedItem>
。したがって、上記のように宣言することは不可能ExtendedCollection
です。これにより、コンパイルエラーが発生します。
The type 'Demo.ExtendedItem' must be convertible to
'Demo.FlexItem<Demo.ExtendedItem>' in order to use it as parameter 'T'
in the generic type or method 'Demo.BasicCollection<T>'
そのようなタイプの衝突を回避する方法はありますか?