2016-04-29 10 views
0

List多くの種類のオブジェクトが含まれていますが、これらの型は共通の基本クラスModelBaseを1つ持っています。各タイプの一般的なListタイプは一意です。つまり、同じタイプを含む2つのリストはありません。リストを取得<T>コレクションから(C#)

最後に、私は、ジェネリック型として、またはパラメータのいずれかとしてModelBaseから派生したオブジェクトの型を取り、そのジェネリック型のそれぞれのList<TModel>を返すpublic List<TModel> GetModelList<TModel>()のような機能を持っていると思います。

これを達成するためにはどのようなオプションが必要ですか?

IはDictionary<Type, List<ModelBase>>について考えたが、その後、私は私はそれを再度フェッチする際格納する基本クラスタイプModelBase及び他の方法ラウンドにサブクラスタイプ(例えばAreaModel)からキャスト。私は、保存する前に、または読み込んだ後にリストをキャストする必要はありません。これを単純化する方法はありますか?私たちが引数として渡したいタイプのListを渡しているので、キャストを自動化できるかどうか?

答えて

1

リストをオブジェクトとして内部辞書に格納し、必要に応じて指定された型にキャストするだけです。そのリストはそのタイプではないので、リストをモデルリストのリストとして格納しようとすると意味がありません。このような

何か:

public class Container {  
    private readonly ConcurrentDictionary<Type, object> _container = 
     new ConcurrentDictionary<Type, object>(); 

    public List<TModel> Get<TModel>() where TModel: ModelBase { 
     return _container.GetOrAdd(typeof(TModel), t => new List<TModel>()) as List<TModel>;   
    } 
} 

私は確信して唯一の単一のリストインスタンスが種類ごとに作成されていることを確認するために、同時辞書を使用しています。必要に応じて、既存のリストを辞書に保存するメソッドを簡単に追加できます。

// Usage 
var container = new Container(); 
var person = container.Get<Person>(); 
var orders = container.Get<Order>(); 
+0

、「ConcurrentDictionaryは、スレッドの安全性にのみ関連ですが、私はドン本当にそれが必要です。通常の辞書の代わりにそれを選んだ理由は何ですか? 「それぞれのタイプに対して1つのリストインスタンスしか作成されていないことを確認してください」という意味を理解していません。これは通常の辞書でも同じですか、そうではありませんか? –

+0

通常の辞書の代わりにConcurrentDictionaryを使うなど、自分のクラスをスレッドセーフなものにすることができれば、そうします。そして、もしあなたがシングルスレッド環境でしか使用しないなら、通常の辞書は正常に動作しますが、便利な '.GetOrAdd(..)'メソッドはありません。 – Maarten

1

public List<Person> GetPersons() 
{ 
    var table = context.ExecutDataTable(); 
    return GetModelList<Person>(table); 
} 

public List<T> GetModelList<T>(DataTable table) where T : ModelBase, new() 
{   
    var list = new List<T>(); 
    foreach(DataRowView row in table.DefaultView) 
    { 
     var item = new T(); 
     t.Load(row); 
     list.Add(item); 
    } 
    return list; 
} 

それとも、Cast拡張メソッドを使用することができますについて。このソリューションは、あなたが常にList<ModelBase>を返し、データ層にメソッドを持っていますが、あなたが望む結果をアーカイブする他の方法があり、あなたのリストには、唯一のPersonオブジェクト

public List<Person> GetPersonList() 
{ 
    // returns a List<ModelBase> 
    var persons = context.ExecuteList("SELECT * FROM person"); 
    return persons.Cast<Person>().ToList(); 
} 
1

が含まれていることを確認している場合、あなたが作成することができます理にかなっています静的クラス:

static class Store<TModel> where TModel : ModelBase 
{ 
    public static readonly List<TModel> List = new List<TModel>(); 
} 

このようにして、それぞれStore<T>のリストがあります。 もう一つの方法は、Monostate Patternを使用している:

class Store2<TModel> where TModel : ModelBase 
{ 
    static readonly List<TModel> list = new List<TModel>(); 
    public List<TModel> List { get { return list; } } 
} 

を次にあなたはこのようにそれを使用することができます:MSDNを見てたから

var storeA = new Store<ModelA>(); 
storeA.List.Add(new ModelB()); 

var storeB = new Store<ModelB>(); 
storeB.List.Add(new ModelB()); 
関連する問題