如何实现支持任意类级别查询的继承基类对象注册表?
解决方案
核心思路是在注册实体时,将其同时加入自身类型及所有父类(直至Entity)对应的列表,这样查询时可直接通过类型键获取所有符合要求的实体,查询效率为O(1),注册时的额外开销为一次性成本,完全可接受。
具体实现
1. 新增类型继承链缓存与辅助方法
为避免重复计算同一类型的继承链,添加静态字典缓存类型对应的继承链列表:
public class EntityRegistry { private Dictionary<int, Entity> _idMap = new Dictionary<int, Entity>(); private Dictionary<Type, List<Entity>> _typeMap = new Dictionary<Type, List<Entity>>(); // 缓存类型的继承链,避免重复计算 private static readonly Dictionary<Type, List<Type>> _typeChainCache = new Dictionary<Type, List<Type>>(); // 获取类型的完整继承链(含自身,直至Entity) private List<Type> GetInheritanceChain(Type type) { if (_typeChainCache.TryGetValue(type, out var chain)) return chain; var chainList = new List<Type>(); var currentType = type; // 遍历至Entity基类,排除object while (currentType != null && currentType != typeof(object)) { chainList.Add(currentType); currentType = currentType.BaseType; } _typeChainCache[type] = chainList; return chainList; } // ... 其他方法 }
2. 修改注册方法,同步更新所有父类列表
修改RegisterEntity,将实体添加到继承链上所有类型的列表中:
public void RegisterEntity(Entity entity) { entity.Id = GetNextEntityId(); _idMap[entity.Id] = entity; var entityType = entity.GetType(); var typeChain = GetInheritanceChain(entityType); foreach (var type in typeChain) { if (!_typeMap.ContainsKey(type)) { _typeMap[type] = new List<Entity>(); } _typeMap[type].Add(entity); } }
3. 实现按类型查询的方法
新增GetAllEntities<T>方法,直接返回指定类型(含子类)的所有实体:
public IEnumerable<T> GetAllEntities<T>() where T : Entity { var targetType = typeof(T); if (_typeMap.TryGetValue(targetType, out var entities)) { foreach (var entity in entities) { yield return (T)entity; } } yield break; }
4. 优化原有ID查询方法
为原有GetEntity<T>添加类型检查,避免无效转换:
public T GetEntity<T>(int entityId) where T : Entity { if (_idMap.TryGetValue(entityId, out var instance) && instance is T tInstance) { return tInstance; } return default; }
方案优势
- 查询高效:直接从字典获取目标列表,无需遍历所有实体进行类型判断,时间复杂度O(1)
- 注册开销可控:同一类型的继承链仅计算一次,后续同类型实体注册直接复用缓存结果
- 语义清晰:完全贴合面向对象的继承规则,查询
Vehicle会自动包含Submarine、Car等子类实例
内容的提问来源于stack exchange,提问作者Satchmo Brown
相关产品推荐
相关产品推荐

