我可以定义一个Type变量,表示特定类的子类型的类型是唯一有效的值吗?

时间:2013-04-12 00:43:31

标签: c# types

背景

我正在为一个小型个人游戏项目编写一些组件(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

我特别感兴趣的是这是否可能 - 在替代方法中没有那么多(我知道几个,它们只包括允许这种行为,因为我是唯一一个与之合作的人这段代码。

2 个答案:

答案 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,但如果不接受,则可以添加CreateControllerCreateComponent等工厂重载一个受限于独特的界面。

答案 1 :(得分:1)

不幸的是,不是直接 - 虽然你可以在泛型中约束参数,但是输入变量就像你的MetaType字段一样不能被约束。这基本上就像试图约束int:你可以使用异常来确保它永远不会设置为无效值,但最终变量本身可能是正确类型的任何东西。