2

我目前正在基于 Unity 的装饰器模型构建自己的游戏引擎。我有三个类(SceneStateManager(一次只控制一个场景)> 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;
    }
}

场景状态管理器:

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>

接口 IInitializable:

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

不幸的是,除非在 T 中IInitializable<T>是协变的,否则结论不是从前提得出的。由于您的实际实现有一个接受 T 的方法,因此它T 中不能是协变的。

这样想吧。AnIInitializable<T>就像一个可以放入的容器T。约束说“你需要给我一个TItem这样的东西,它是一个我可以放入任何 SceneSystemJob<TItem>东西的容器。” 你给了它一个你只能放进去的容器GameObject。因此不满足约束。

这就像约束说“我需要一个可以容纳任何动物的笼子”,而你正在给它一个水族馆。嗯,这是一个可以容纳任何鱼的笼子,但约束并没有说“我需要一个笼子来容纳一些动物,你的选择”,它说它需要一个笼子来容纳任何动物。

我不知道你如何解决你自己陷入的这个烂摊子,而不是重新开始而不是过于笼统。

于 2013-09-13T18:12:49.193 回答