You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现支持任意类级别查询的继承基类对象注册表?

解决方案

核心思路是在注册实体时,将其同时加入自身类型及所有父类(直至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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 23:25:20