Skip to main content
 首页 » 编程设计

c#之在运行时从具有泛型类型的集合中选择值

2024年02月25日37开发

我有一个池集合

private Dictionary<Type, object> componentPools = new Dictionary<Type, object>(); 

每个池都可以通过其类型来识别。 object总是 Dictionary<Guid, TComponent>()其中 TComponent作为通用类型实现接口(interface) IComponent Guid 代表一个唯一的 ID 作为键。

仅供引用,这些池的基本补充是

public void AddComponentPool<TComponent>() where TComponent : IComponent 
{ 
    componentPools.Add(typeof(TComponent), new Dictionary<Guid, TComponent>()); 
} 

我想返回一个 Type 的数组填充了连接到 Guid 的类型.一开始我尝试使用又长又丑的run

List<Type> componentTypesList = new List<Type>(); 
 
foreach (KeyValuePair<Type, object> componentPool in componentPools) 
{ 
    Dictionary<Guid, object> pool = (Dictionary<Guid, object>)componentPool.Value; 
 
    if (pool.Keys.Contains(entityId)) 
    { 
        componentTypesList.Add(componentPool.Key); 
    } 
} 
 
Type[] componentTypes = componentTypesList.ToArray(); 

但是这段代码无论如何都不起作用。

Dictionary<Guid, object> pool = (Dictionary<Guid, object>)componentPool.Value;崩溃是因为 Value应该是 TComponent而不是 object .

我也尝试过使用 Linq,但这更糟糕,也不起作用。

            Type[] componentTypes = componentPools 
                .Select(pool => pool.Key) 
                .Where(pool => (Dictionary<Guid, object>)pool.Keys.Contains(entityId)) 
                .ToArray(); 

需要修复什么?


更新:

为了弄清楚一些事情,TComponent是通用的,在我想使用的方法中不可用。我的伪代码方法是

    public Type[] GetTypesById(Guid entityId) 
    { 
        List<Type> componentTypes = new List<Type>(); 
 
        foreach (KeyValuePair<Type, object> componentPool in componentPools) 
        { 
            Dictionary<Guid, object> pool = (Dictionary<Guid, object>)componentPool.Value; 
 
            if (pool.Keys.Contains(entityId)) 
            { 
                componentTypes.Add(componentPool.Key); 
            } 
        } 
 
        return componentTypes.ToArray(); 
    } 

按照@Adam 的要求,完整的代码

https://pastebin.com/b400Egzp

相关部分是方法AddComponentToEntity .请记住,我不是经验丰富的程序员 :)

请您参考如下方法:

查看this answer ,您可以先尝试转换为 IDictionary 并解决这个问题:

public Type[] GetTypesById(Guid entityId) 
{ 
    return componentPools 
              .Where(x => ((IDictionary)x.Value) 
                  .Contains(entityId)) 
              .Select(x => x.Key) 
              .ToArray(); 
}