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

时间:2019-01-20 19:59:05

标签: c#

我有一个游泳池的集合

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

每个池都可以通过其类型进行标识。 object始终为Dictionary<Guid, TComponent>(),其中TComponent作为通用类型实现了接口IComponent,而Guid代表唯一的ID作为密钥。

仅供参考,这些池的基本补充是

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

我想返回一个Type数组,该数组填充有连接到Guid的类型。起初,我尝试使用漫长而丑陋的运行方式

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是通用的,在我要使用的方法中不可用。我的 PseudoCode 方法是

    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。请记住,我不是一个经验丰富的程序员:)

1 个答案:

答案 0 :(得分:3)

看看this answer,您可以尝试先投射到IDictionary并加以解决:

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