通过集合中的泛型类型T获取列表<t>(C#)

时间:2016-04-29 07:21:25

标签: c# list generics dictionary collections

我有很多List个包含不同类型的对象,但所有这些类型都有一个共同的基类ModelBase。每种通用List类型都是唯一的,即不会包含两个包含相同类型的列表。

最后,我希望有一个像public List<TModel> GetModelList<TModel>()这样的函数,它将从ModelBase派生的任何对象的类型作为泛型类型或参数,然后返回相应的List<TModel>那种泛型。

我有什么选择来实现这个目标?

我考虑了Dictionary<Type, List<ModelBase>>,但后来我从子类类型(例如AreaModel)转换为基类类型ModelBase进行存储,反之亦然再次。我不希望每次在存储之前或加载之后都要编制列表。有没有办法简化这个?也许我们可以自动化演员阵容,因为我们正在传递我们想要的List类型作为参数?

3 个答案:

答案 0 :(得分: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>();

答案 1 :(得分: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();
}

答案 2 :(得分: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; } }
}

然后你可以像这样使用它:

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

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