我正在为一个小型个人游戏项目编写一些组件(this kind of component)。在该系统中,实体具有属于各种类别的各种类型的组件。例如, IController 组件类别包括 KeyboardController 和 AiController 。实体具有组件集合,并且每个类别应该只有一个组件。所有组件都继承自 IComponent 。
组件有一个 MetaType 属性,它应该报告它们对应的类型,以便说:“嘿,请把我视为这种类型的组件!”此属性返回 Type 对象。 AiController 返回 typeof(IController),告诉实体将其视为其控制器。其他有效的元类型将是 typeof(AiController)或 typeof(IComponent)。它不应该能够返回任何类型,例如 typeof(int) - 只是组件类型。
目前,我的组件可以报告MetaType的任意类型。例如, AIController 实际上可以返回 typeof(int) - 毕竟这是一个有效的Type对象。
我可以约束 Type 值,以便唯一有效的类型是 IComponent 是祖先的任何类或接口的类型吗?我想这样的变量声明可能如下所示:
Type<IComponent> component; // This can only store certain types
Type where Type : IComponent component; // This too
我特别感兴趣的是这是否可能 - 在替代方法中没有那么多(我知道几个,它们只包括允许这种行为,因为我是唯一一个与之合作的人这段代码。
答案 0 :(得分:3)
您可以创建一个MetaType
对象,其构造函数或工厂方法将采用约束IComponent
的泛型类型,并提供对非约束Type
的访问。但由于它的构造函数受到限制,因此应保证不会获得其他非IComponent。
public class MetaType
{
public Type ComponentType { get; private set; }
private MetaType(Type componentType)
{
this.ComponentType = componentType;
}
public static MetaType Create<T>() where T : IComponent
{
return new MetaType(typeof(T));
}
}
您的用法可能如下:
MetaType validType = MetaType.Create<IComponent>(); //fine
MetaType validType = MetaType.Create<IController>(); //fine
MetaType validType = MetaType.Create<AIController>(); //fine
MetaType invalidType = MetaType.Create<int>(); //compiler error!
编辑:我假设您的IController
接口继承自IComponent
,但如果不接受,则可以添加CreateController
和CreateComponent
等工厂重载一个受限于独特的界面。
答案 1 :(得分:1)
不幸的是,不是直接 - 虽然你可以在泛型中约束参数,但是输入变量就像你的MetaType
字段一样不能被约束。这基本上就像试图约束int
:你可以使用异常来确保它永远不会设置为无效值,但最终变量本身可能是正确类型的任何东西。