实现一个非常特殊的通用签名
本文关键字:非常 一个 实现 | 更新日期: 2023-09-27 18:31:08
我目前正在基于 Unity 的装饰器模型构建自己的游戏引擎。我有三个类(SceneStateManager(一次只控制一个场景)>场景>SceneLayer>游戏对象>组件),它们构成了场景层次结构,除了名称和一些较小的、非常具体的功能外,它们基本上都是相同的。(在这种情况下,重写方法将执行此操作)
所有类都可以从父层次结构级别类类型初始化,并控制多个子类。由于类共享了许多通用功能,因此我想让它们从基类派生,该基类对共享功能进行分组以简化代码。
"超级基类"(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>
接口 II 可数字化:
public interface IInitializable<TParent>
{
void Initialize(TParent parent);
}
如果您仍然需要更多代码,请告诉我。
从一个更简单的系统重新开始之外,我不知道如何解决您的问题。这似乎非常过度设计。
为了解释为什么你的代码是错误的,看看这个大大简化的版本:
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>>
的标准
不幸的是,除非IInitializable<T>
在T中是协变的,否则结论不是从前提得出的。由于您的实际实现具有接受 T 的方法,因此它不能在 T 中协变。
这样想一想。IInitializable<T>
就像一个容器,您可以将T
放入其中。 约束说:"你需要给我一个TItem
,这样我就可以把任何SceneSystemJob<TItem>
放进去。你给它一个你只能把GameObject
放进去的容器。因此,不满足约束。
这就像约束说"我需要一个可以容纳任何动物的笼子",而你递给它一个水族馆。嗯,这是一个可以容纳任何鱼的笼子,但约束并没有说"我需要某种动物的笼子,你的选择",它说它需要一个笼子来容纳任何动物。
我不知道你如何解决你让自己陷入的这个烂摊子,除了重新开始,不要那么过于笼统。