无法使用反射时,如何快速查找Service子类列表中的指定泛型实例?
问题背景
我有一个基类Service:
class Service { }
同时存在多个继承自Service的子类:
class Service1 : Service { } class Service2 : Service { } class Service3 : Service { } ...
这些子类的实例都存储在同一个List<Service>集合中:
List<Service> services = new List<Service>() { new Service1(), new Service2(), new Service3() };
由于不能使用反射,我当前用以下方法查找指定类型的实例:
public T GetService<T>() where T : Service { foreach (var service in services) { if (service is T) return (T)service; } return null; } // 调用示例 var instance = GetService<Service1>();
现在的问题是:当集合中的元素数量足够多时,如何实现更快速的查找?
优化方案
1. 构建类型-实例映射字典
一次性遍历原始集合,将每个实例按其实际类型存入Dictionary<Type, Service>,后续查找直接利用字典的O(1)时间复杂度索引,这是最直接高效的优化方式。
单实例场景(同类型仅存一个实例)
// 类内维护映射字典 private Dictionary<Type, Service> _serviceMap; // 在services集合初始化完成后执行映射构建 private void InitServiceMap() { _serviceMap = new Dictionary<Type, Service>(); foreach (var service in services) { // 若存在同类型多个实例,后遍历的会覆盖先存入的,根据业务需求调整 _serviceMap[service.GetType()] = service; } } // 优化后的查找方法 public T GetService<T>() where T : Service { if (_serviceMap.TryGetValue(typeof(T), out var target)) { return (T)target; } return null; }
多实例场景(同类型存在多个实例)
如果允许同类型有多个实例,可将字典的值改为List<Service>来存储同类型的所有实例:
private Dictionary<Type, List<Service>> _serviceMap; private void InitServiceMap() { _serviceMap = new Dictionary<Type, List<Service>>(); foreach (var service in services) { var serviceType = service.GetType(); if (!_serviceMap.ContainsKey(serviceType)) { _serviceMap[serviceType] = new List<Service>(); } _serviceMap[serviceType].Add(service); } } // 获取同类型所有实例 public List<T> GetServices<T>() where T : Service { if (_serviceMap.TryGetValue(typeof(T), out var instances)) { return instances.Cast<T>().ToList(); } return new List<T>(); } // 获取同类型第一个实例 public T GetService<T>() where T : Service { return GetServices<T>().FirstOrDefault(); }
2. 使用ILookup分组存储
如果services集合不会动态修改,可使用.NET内置的ILookup<Type, Service>完成分组,它的查找效率和字典一致,且语法更简洁:
private ILookup<Type, Service> _serviceLookup; private void InitServiceLookup() { _serviceLookup = services.ToLookup(s => s.GetType()); } public T GetService<T>() where T : Service { return _serviceLookup[typeof(T)].Cast<T>().FirstOrDefault(); }
3. 动态集合的同步维护
如果services集合需要动态增删实例,必须同步更新映射字典或分组集合,保证查找结果准确:
// 添加服务时同步更新字典 public void AddService(Service service) { services.Add(service); var serviceType = service.GetType(); if (_serviceMap.ContainsKey(serviceType)) { _serviceMap[serviceType].Add(service); } else { _serviceMap[serviceType] = new List<Service> { service }; } } // 删除服务时同步更新字典 public void RemoveService(Service service) { services.Remove(service); var serviceType = service.GetType(); if (_serviceMap.TryGetValue(serviceType, out var instances)) { instances.Remove(service); if (instances.Count == 0) { _serviceMap.Remove(serviceType); } } }
内容的提问来源于stack exchange,提问作者srnldai
相关产品推荐
相关产品推荐

