「何でも」(C#の)のジェネリックコレクションを返すメソッドを宣言する方法
-
12-09-2019 - |
質問
私はまた、抽象基本クラスから派生したエンティティの項目を格納する抽象基本クラスから派生するジェネリックコレクションクラスの階層を使用しています:
abstract class ItemBase { }
class MyItem : ItemBase
{
public MyItem()
{
}
}
abstract class CollectionBase<T> : Collection<T> where T : ItemBase, new() { }
class MyCollection : CollectionBase<MyItem> { }
このモデルの目的は、
今、私はCollectionBaseに
public CollectionBase<T> CreateCollection<T>();
...または多分...
public T Create CreateCollection<T>();
しかし、問題は、呼び出し元のルーチンは、「T」が必要になるのか分からないということです。これは、コレクションの特定のタイプを返すように決定する必要がありますファクトリメソッドそのものです。だから私は、「戻り値の型は、
public CollectionBase<> CreateCollection();
私は、これは、それらの厄介な一般的な分散の問題の他であると仮定し、それでも対象にエリックリペットの広範な説明を読んだ後、私はまだ私は何をしようとしていますが、C#4.0で実現可能である可能性が高いかどうかは不明だ、とするかどうかがC#の3.0で簡単な回避策です。
あなたのアイデアを事前に感謝します。
解決
のは、ファクトリメソッドは、単一の項目を作成したとしましょう。あなたが持っているでしょう。
public ItemBase CreateItem();
あなたはより具体的な何かを知ることができないのでItemBase
を使用する必要があります。収集方法にその原則を適用すると、次のようになります。
public CollectionBase<ItemBase> CreateCollection();
により分散の不足のために、あなたはCollectionBase<ItemBase>
から派生して作成された実際のコレクションをラップアダプタクラスを必要とします。
C#4.0では、あなただけの実際のコレクションを返します。
の編集の工場は、組み込みアダプターで、次のようになります。
public class CollectionFactory
{
public CollectionBase<ItemBase> CreateCollection()
{
if(someCondition)
{
return CreateAdapter(new MyCollection());
}
else
{
return CreateAdapter(new MyOtherCollection());
}
}
private static CollectionAdapter<T> CreateAdapter<T>(CollectionBase<T> collection) where T : ItemBase, new()
{
return new CollectionAdapter<T>(collection);
}
private class CollectionAdapter<T> : CollectionBase<ItemBase> where T : ItemBase, new()
{
private CollectionBase<T> _collection;
internal CollectionAdapter(CollectionBase<T> collection)
{
_collection = collection;
}
// Implement CollectionBase API by passing through to _collection
}
}
他のヒント
おそらく、何が必要です。
public CollectionBase<Object> CreateCollection();
すべてのクラスは、直接的または間接的にオブジェクト・クラスから継承するので
私は実際にこれを行って、謝罪していません
public CollectionBase<Object> CreateCollection();
あなたは本当にそれが何になりたい場合は、あなただけいるICollectionを返すことができて、彼らが必要として、あなたの消費者は.Cast<ItemBase>()
拡張メソッドを呼び出すことができます。
私が理解から、.NET 4.0で、あなたはCollectionBase<ItemBase>
を返すことができるだろうが、私はまだベータ版でそれを試していません。