2

現在、Unity のデコレータ モデルに基づいて独自のゲーム エンジンを構築しています。シーン階層を構成する 3 つのクラス (SceneStateManager (一度に 1 つのシーンのみを制御) > Scene > SceneLayer > GameObject > Component) があり、名前といくつかの小さな非常に特殊な機能を除いて、基本的にすべて同じです。(この場合、メソッドをオーバーライドするとそれが行われます)

すべてのクラスは、親階層レベルのクラス タイプから初期化可能であり、多数の子を制御します。クラスによって共有される多くの共通機能があるため、コードを簡素化するために共有機能をグループ化する基本クラスからクラスを派生させたいと考えています。

「スーパー基本クラス」(ListJob<T>)は子を制御するクラスであり、これまで、少なくともその部分を単純化するために、前述のすべての型がそこから派生しています。したがって、子の処理自体は、既に非常にうまく機能しているため、ここのコードに含める必要はありません。

将来、すべてのシーン階層クラスの派生元となるベース クラスの適切なジェネリック シグネチャを取得する必要があります。私の現在のソリューションは、このエラーでコンパイルされません: http://msdn.microsoft.com/en-us/library/bb384252(v=vs.100).aspx


ジェネリック シグネチャと SceneSystemJob クラスの現在のバージョン:

public abstract class SceneSystemJob<TItem, TParent> : ListJob<TItem>, IInitializable<TParent>  
    where TItem : IInitializable<SceneSystemJob<TItem, TParent>>
{  
    private TParent _Parent = default(TParent);

    public TParent Parent
    {
        get
        {
            return _Parent;
        }
        protected set
        {
            _Parent = value;
        }
    }

    // Implementation

    public void Initialize(TParent parent)
    {
        this.Parent = parent;
    }
}

SceneStateManager:

public class SceneStateManager // Controls only one Child and does not derive from super base class

シーン:

public class Scene : SceneSystemJob<SceneLayer, SceneStateManager>

シーンレイヤー:

public class SceneLayer : SceneSystemJob<GameObject, Scene>

ゲームオブジェクト:

public class GameObject: SceneSystemJob<Component, SceneLayer>

成分:

public abstract class Component : Manager, IInitializable<GameObject>

インターフェイス II初期化可能:

public interface IInitializable<TParent>
{  
    void Initialize(TParent parent);  
}

さらにコードが必要な場合は、教えてください。

4

1 に答える 1

5

はるかに単純なシステムからやり直す以外に、あなたの問題を解決する方法がわかりません。これは非常に過剰に設計されているようです。

コードが間違っている理由を説明するには、次の非常に単純化したバージョンを見てください。

public interface IInitializable<TParent> { }
public class SceneSystemJob<TItem>  
    where TItem : IInitializable<SceneSystemJob<TItem>>
{ }
public class GameObject : SceneSystemJob<Component> { } // Error here
public class Component : IInitializable<GameObject> { }

エラーは、Componentとして使用できないことTItemです。なぜだめですか?これがうまくいくはずだと思われます:

  • TItemを実装する必要がありますIInitializable<SceneSystemJob<TItem>>
  • Component実装しますIInitializable<GameObject>
  • GameObjectの特別な種類ですSceneSystemJob<Component>>
  • したがってComponent、実装の基準を満たしていますIInitializable<SceneSystemJob<Component>>

残念ながら、 が TIInitializable<T>で共変でない限り、結論は前提から従いません。実際の実装には T を受け取るメソッドがあるため T で共変することはできません。

このように考えてみてください。anIInitializable<T>は、 a を入れる容器のようなものですT制約は、「私が何でもTItem入れることができるコンテナであるように私に与える必要がある」と言います。あなただけが入れられる容器を与えているのです。したがって、制約は満たされていません。 SceneSystemJob<TItem>GameObject

「どんな動物でも入れられるケージが必要だ」という制約があり、それを水槽に渡しているようなものです。まあ、それはどんな魚でも入れることができるケージですが、制約は「私はいくつかの動物のためのケージが必要です、あなたの選択」とは言っていません

最初からやり直すことと、過度に一般的ではないこと以外に、自分が陥ったこの混乱をどのように修正するかはわかりません。

于 2013-09-13T18:12:49.193 に答える