3

これは 2 部構成の質問です。

まず
、次のような ComponentList というクラスがあります。

public class ComponentList<T> : List<T> where T : Component
{

}

ここで、型のない ComponentList の空のリストを作成したいと思います。

List<ComponentList<>> MasterList = new List<ComponentList<>>();

ComponentList をまだ初期化しようとしていなくても (ComponentList を含む MasterList だけを)、ComponentList がジェネリック型を指定する必要があるため、エラーが発生します。ComponentLists を初期化せずに ComponentLists の MasterList を宣言するにはどうすればよいでしょうか (実行時にのみ認識される型で実行時に初期化する予定であるため)。結局のところ、MasterList には、1 つだけでなく、さまざまなジェネリック タイプの ComponentList が含まれている必要があります。

第二
に、これが以前に尋ねられたことは知っていますが、提案されたソリューションの概念に頭を悩ませているようには見えません。

ご存知のように、List<>ComponentLists (カスタム クラス) のリストである MasterList という名前があります。ComponentList は、未定義の型のジェネリック クラスです (Component のサブタイプに制限されています)。

次の例では、ComponentList ジェネリック型 (MasterList から参照) がこのクラス (コードの呼び出し元のクラス) と同じかどうかを確認しようとしています。

if (MasterList[i].GetType() == typeof(ComponentList<this.GetType()>))
{

}

問題は、コードが、この親クラスからではなく、未知の子クラスから自動的に呼び出されることを意図していることです。したがって、ComponentList ジェネリック型は、この基本クラスではなく、子クラスの型と比較する必要があります。したがって、実際の基本クラスのハードコードされた名前の代わりに「this.GetType」が使用されます。

this.GetType()ComponentList<> で渡された型は、実行時の型ではなくコンパイル時の型を返すため、明らかに「型が必要です」というエラーを返しGetType()ます(これが必要です)。

では、ランタイム タイプを取得するにはどうすればよいでしょうか。それができない場合、私がやろうとしていることを達成するための最良の代替手段は何でしょうか? (リフレクションと呼ばれるものが役立つかもしれないという話を少し聞いたことがありますが、よくわかりません)。

4

3 に答える 3

0

C# で作成されたゲームのエンティティ コンポーネント システムをセットアップしようとしたときにも、この問題に遭遇しました。コンポーネントを実際の型として格納する方法は実際にはありません。すべてをComponents として格納し、キャストする必要があります。

私が設定した方法は、クラスDictionary<Type, List<Component>>のプライベートメンバーとしてです。ComponentManagerコンポーネントを追加するメソッドは一般的であり、その Type が Dictionary に含まれているかどうかを確認するため、取得IEnumerable<SpecificComponent>は次のように簡単です。

public IEnumerable<T> EnumerateComponents<T>()
    where T : Component
{
    foreach (Component c in components[typeof(T)])
        yield return (T)c;
}

(辞書に が含まれていることも確認する必要がありますtypeof(T)。そのビットは、このような場合の例外を回避するために Dictionary から継承する私のカスタム コレクションに組み込まれています。)

ディクショナリがジェネリック メソッドの外部で変更されない限り (そして、外部から直接アクセスできないことは間違いありません)、型の安全性は "保証" されます。理想的ではありませんが、ボトルネックにならないほど十分に高速です。

編集

探求すべきことは、C# 4 のdynamicキーワードかもしれません。私はそれをあまり調べていませんが、コンポーネントを として保存すると、List<dynamic>よりうまく機能する可能性があります (または、オーバーヘッドが非常に大きくなる可能性があります)。

于 2013-05-03T05:35:27.420 に答える
-1

あなたが求めていることは可能だとは思いませんが、これが必要なのかもしれません。

public class ComponentA : Component { }
public class ComponentB : Component { }
public class Component { }

public class ComponentList<T> : List<T> where T : Component
{

}

class Program
{
    static void Main(string[] args)
    {
        ComponentList<Component> MasterList = new ComponentList<Component>();

        MasterList.Add(new ComponentA());
        MasterList.Add(new ComponentB());

        for (int i = 0; i < MasterList.Count; i++)
        {
            if (MasterList[i] is ComponentA)
            {
            }

        }
    }
}
于 2013-05-03T03:37:53.193 に答える