public class ItemStore {
private Dictionary<Type, List<object>> _items = new Dictionary<Type, List<object>>();
public void AddItem(object item) {
var type = item.GetType();
if (!_items.ContainsKey(type)) {
_items[type] = new List<object>();
}
_items[type].Add(item);
}
public IEnumerable<T> GetItems<T>() {
if(!_items.ContainsKey(typeof(T))) {
return new List<T>();
}
return _items[typeof(T)].Cast<T>();
}
}
Run Code Online (Sandbox Code Playgroud)
(真实场景更复杂,它是一个在多个项目中使用的库,对于具体类型一无所知....)
将Cast<T>()在GetItems()会消耗相当长的一段时间.所以我宁愿避免它.有没有办法在C#中避免它 - 因为实际上列表已经包含了正确的类型?
您需要稍微修改此类的内部结构,以便在项目查找中不使用泛型,因为我们需要将存储列表的基础类型作为正确的类型.创建列表时需要稍加反思.我们还可以通过避免额外的查找来使AddItem和GetItems更有效:
public class ItemStore {
private Dictionary<Type, IList> _items = new Dictionary<Type, IList>();
public void AddItem(object item) {
var type = item.GetType();
IList list;
if (!_items.TryGetValue(type, out list)) {
var listType = typeof(List<>).MakeGenericType(type);
list = (IList)Activator.CreateInstance(listType);
_items[type] = list;
}
list.Add(item);
}
public IEnumerable<T> GetItems<T>() {
IList list;
if(!_items.TryGetValue(typeof(T), out list)) {
return Enumerable.Empty<T>();
} else {
return (IEnumerable<T>)list;
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果你可以修改AddItem的签名,这可能更简单(没有反射),但鉴于你说这是一个过度简化,我将保持公共API不变.
| 归档时间: |
|
| 查看次数: |
107 次 |
| 最近记录: |