我有很多List
个包含不同类型的对象,但所有这些类型都有一个共同的基类ModelBase
。每种通用List
类型都是唯一的,即不会包含两个包含相同类型的列表。
最后,我希望有一个像public List<TModel> GetModelList<TModel>()
这样的函数,它将从ModelBase
派生的任何对象的类型作为泛型类型或参数,然后返回相应的List<TModel>
那种泛型。
我有什么选择来实现这个目标?
我考虑了Dictionary<Type, List<ModelBase>>
,但后来我从子类类型(例如AreaModel
)转换为基类类型ModelBase
进行存储,反之亦然再次。我不希望每次在存储之前或加载之后都要编制列表。有没有办法简化这个?也许我们可以自动化演员阵容,因为我们正在传递我们想要的List
类型作为参数?
答案 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());