2011-07-08 26 views
2

私はちょっとした試合をしました。今、私は現在の "エンティティ"オブジェクトと衝突している特定のタイプのすべてのアイテムのリストを取得したいと思います。私は次のエラーを取得するC#:連鎖Linqメソッドとキャスト

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>" 

誰も説明でき、これはなぜ起こるか私はこのような何かをしたいですか?

ありがとうございました!

+0

、:

Enumerable.Select<TSource, TResult>Enumerable.OfType<TResult>は、ソースとは異なるタイプのIEnumerableをを返すことができます。 2番目の 'Where'節は' OfType () 'に置き換えることができます。 –

答えて

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(); 
} 
+0

+1:また、シナリオによっては、.OfType ()を '.AsParallel()'の前に置く方が良いでしょう。エンティティ内のタイプの非ランダムな分布(可能性が高い)。 –

+0

@Reed:ああ、良い点。 'OfType()'が 'AsParallel()'の前後に来るべきかどうかについて私は議論していました。 –

+0

こんにちは、あなたの説明に感謝します:-)それは素晴らしい作品!そして、なぜそれが最初に機能しなかったのか理解しました。 – kpko

0

ジェフ・メルカドの答えは正しいですが、より分かりやすく述べることができます。

.Where(e => e is T) 

Enumerable.Where<Entity>戻りIEnumerable<Entity>IEnumerable<Entity>あるソースのフィルタリングされたバージョン)この呼び出し。呼び出しはIEnumerable<T>を返しません。それはおそらくあなたの問題を解決することはできません

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

または

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

または

.OfType<T>() 
関連する問題