背景
我正在为一个小型个人游戏项目编写一些组件(这种组件(。在该系统中,实体具有属于各种类别的各种类型的组件。例如,IController类别的组件包括KeyboardController和AiController。一个实体有一个组件集合,每个类别中应该只有一个组件。所有组件都继承自IComponent。
组件有一个MetaType属性,该属性应该报告它们对应的类型,以便说:"嘿,请把我当作这种类型的组件!"此属性返回一个typeobject。AiController返回typeof(IController(,告诉实体将其视为其控制器。其他有效的MetaTypes是typeof(AiController(或type of(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
我特别感兴趣的是这是否可能-在替代方法中不太感兴趣(我知道有几种,其中包括允许这种行为,因为我是唯一一个使用此代码的人。
您可以创建一个MetaType
对象,其构造函数或工厂方法将采用针对IComponent
约束的泛型类型,并提供对非约束Type
的访问。但是由于它的构造函数是受约束的,所以应该保证不会得到其他非IC组件。
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
,每个重载都受唯一接口的约束。
不幸的是,不是直接的-虽然您可以在泛型中约束类型参数,但类型variable(如MetaType
字段(不能被约束。这基本上就像试图约束int
:您可以使用异常来确保它永远不会被设置为无效值,但最终变量本身可以是正确类型的任何值。