2

すべてのオブジェクトは、 と呼ばれる基本抽象クラスから構成されていますGameObject。これらのオブジェクトはすべて、IRenderableIAnimatable、などの 1 つまたは複数のインターフェイスから継承しますIMovable

として保存されているこれらのオブジェクトのリストもありますList<GameObject>。次のように、特定のインターフェイスから継承したすべてのオブジェクトを返す動的メソッドを作成しようとしています。

List<IRenderable> renderableObjects = ObjectManager.GetAll<IRenderable>();

最初は、各オブジェクトの型が動的型と一致するゲーム オブジェクトの新しいリストを返すだけにして、 を にキャストしてList<GameObject>みましたList<T>。私が受け取ったコンパイラ エラーは、これらの型を変換できないことを示していました。

2 回目の試みでは、以下に示すように、各オブジェクトを個別にキャストしました。

public List<T> GetAll<T>() {
    List<T> list = new List<T>();

    foreach( GameObject obj in this.gameObjects )
        if( obj is T )
            list.Add( (T)obj );

     return list;
}

ただし、これは同じタイプのエラーをスローします。タイプ GameObject を T に変換できません。何か不足していますか? 私が望むことを達成する別の方法はありますか?

4

2 に答える 2

5

LINQ には便利なメソッドが既に用意されていますOfType()

List<GameObject> list = ...;
var movableObjects = list.OfType<IMovable>();

OfType指定した型にキャストできる入力シーケンスからのすべての項目を含むシーケンスを返します。さらに、Cast<T>()すべてをキャストしようとしたオペレーターがあり、アイテムをキャストできない場合は例外をスローします (これは、ここで必要なものではないようです)。

于 2012-11-08T21:12:04.900 に答える
4

Servy はより優れたアプローチを提供していますが、コードを簡単に修正することもできます。Tジェネリック型パラメーターに制約を与えるだけです。

public List<T> GetAll<T>() where T : GameObject {

別の (厄介な) 代替手段は、追加のキャストを追加することです。

list.Add((T)(object)obj);

ジェネリック型パラメーターへの変換は少し面倒です。詳細については、 Eric Lippert のブログ投稿を参照してください。

(私は間違いなく Servy のアプローチを使用します。車輪を再発明しても意味がありません。同様の状況でコードを修正する方法を説明したかっただけです。)

于 2012-11-08T21:12:48.303 に答える