Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 遍历泛型词典会引发异常_C#_.net - Fatal编程技术网

C# 遍历泛型词典会引发异常

C# 遍历泛型词典会引发异常,c#,.net,C#,.net,我有以下代码: private Dictionary<int, Entity> m_allEntities; private Dictionary<Entity, List<IComponent>> m_entityComponents; public Dictionary<int, T> GetComponentType<T>() where T: IComponent { Dictionary<int, T>

我有以下代码:

private Dictionary<int, Entity> m_allEntities;
private Dictionary<Entity, List<IComponent>> m_entityComponents;

public Dictionary<int, T> GetComponentType<T>() where T: IComponent
{
    Dictionary<int, T> components = new Dictionary<int, T>();

    foreach (KeyValuePair<int, Entity> pair in m_allEntities)
    {
        foreach (T t in m_entityComponents[m_allEntities[pair.Key]])
        {
            components.Add(pair.Key, t);
        }
    }

    return components;
}
private Dictionary m_allenties;
私有字典m_实体组件;
公共字典GetComponentType(),其中T:IComponent
{
字典组件=新字典();
foreach(m_allenties中的KeyValuePair对)
{
foreach(m_entityComponents[m_allenties[pair.Key]]中的T)
{
组件。添加(pair.Key,t);
}
}
返回组件;
}
m_allenties=所有实体的字典,键:其ID和值:实体对象。 m_entityComponents=所有实体及其组件列表的字典,键为:实体对象和值:组件列表

我有几个实现IComponents接口的不同类。GetComponentType()函数要做的是遍历所有实体,并创建实体ID和特定类型组件的字典

例如:如果我想获得具有位置组件的所有实体的列表,那么我将使用:

entityManager.GetComponentType<Location>();
entityManager.GetComponentType();

我遇到的问题是第二个循环,因为它似乎没有通过我的字典过滤。相反,它尝试将字典中的所有组件强制转换为位置类型,当然,该位置类型会引发异常。如何更改此代码,使其符合我的要求?

如果您的集合具有不同的类型,则需要测试正确的类型

public Dictionary<int, T> GetComponentType<T>() where T: IComponent
{
    Dictionary<int, T> components = new Dictionary<int, T>();

    foreach (KeyValuePair<int, Entity> pair in m_allEntities)
    {
        foreach (IComponent c in m_entityComponents[m_allEntities[pair.Key]])
        {
            if (c is T)
                components.Add(pair.Key, (T)c);
        }
    }

    return components;
}
公共字典GetComponentType(),其中T:IComponent
{
字典组件=新字典();
foreach(m_allenties中的KeyValuePair对)
{
foreach(m_entityComponents[m_allenties[pair.Key]]中的i组件c)
{
if(c是T)
组件。添加(配对键,(T)c);
}
}
返回组件;
}
您可以使用以下方法:

foreach(类型()的m_entityComponents[m_allenties[pair.Key]]中的T)

筛选与您的泛型类型匹配的元素。

谢谢,我刚刚测试了此更改,它甚至不会编译。失败的行是:var t=c as t;。错误:“类型参数'T'不能与'as'运算符一起使用,因为它既没有类类型约束,也没有'class'约束。”@Kittoes-我将忽略错误非常具体的事实。但是,如果你看我的更改,它们消除了类约束的需要。再次感谢你。最后效果很好。jimmy_keen也在下面发布了一个我非常喜欢的解决方案。你会建议使用什么(因为它们都是我所需要的)?@ KITOTES——认为JimMyIGHY提供的解决方案会为你节省一行代码。不过,有人可能会说,这个解决方案效率稍高,因为它只创建了一个较少的迭代器。我是否需要为该功能或其他内容包含一个附加的using语句?@Kittoes:是的,您需要LINQ名称空间。只需使用System.Linq添加
我也这么想,应该在询问之前先尝试添加LINQ。我真的很喜欢这个解决方案,因为我不需要投下任何东西。Chaospanion的上述解决方案也很有效。这两个选项中哪一个更“安全”,这两个选项之间是否存在性能差异?@Kittoes:
of type
在引擎盖下进行
t is t
比较(加上其他一些与LINQ相关的东西)。本质上是一样的。我不会争论什么更有效——一旦编译器这样做,它的工作差异很可能就不存在了。使用能够更好地解释代码用途的解决方案(例如,更具可读性和可理解性等等)。
foreach (T t in m_entityComponents[m_allEntities[pair.Key]].OfType<T>())