C#:链接Linq方法和铸造

时间:2011-07-08 23:23:17

标签: linq casting plinq tolist

我有一个小游戏,在那里我实现了一些碰撞检测。现在我想得到一个特定类型的所有项目的列表,这些项目与当前的“实体”对象发生冲突。我想做这样的事情:

    public List<T> GetCollidingObjects<T>() where T : Entity
    {
        return this.Game.World.Entities
            .AsParallel()
            .Where(e => e.IsColliding(this))
            .Where(e => e is T)
            .ToList<T>();
    }

我收到以下错误:

Instance argument: cannot convert from "System.Linq.ParallelQuery<GameName.GameObjects.Entity>" to "System.Collections.Generic.IEnumerable<T>"

任何人都可以解释,为什么会这样?

谢谢!

2 个答案:

答案 0 :(得分:8)

你不能那样使用ToList()。您提供的通用参数(如果您选择这样做)必须与序列的类型匹配。这是一系列Entity,而不是T

无论如何,您应该使用OfType()进行过滤,这就是它的用途。

public List<T> GetCollidingObjects<T>() where T : Entity
{
    return this.Game.World.Entities
        .OfType<T>()
        .AsParallel()
        .Where(e => e.IsColliding(this))
        .ToList();
}

答案 1 :(得分:0)

杰夫·梅尔卡多的答案是正确的,但可以更清楚地说明。

.Where(e => e is T)

Enumerable.Where<Entity>的此次调用会返回IEnumerable<Entity>(来源的过滤版本,即IEnumerable<Entity>)。该电话不会返回IEnumerable<T>

Enumerable.Select<TSource, TResult>Enumerable.OfType<TResult>可以返回类型与源不同的IEnumerable:

.Where(e => e is T)
.Select(e => e as T)

.Select(e => e as T)
.Where(e => e != null)

 .OfType<T>()