繁体   English   中英

使用泛型的返回类型

[英]Return Type using Generics

首先,提出更好的头衔的建议绝对值得欢迎。

我刚刚开始学习泛型,所以我的知识有限。 我想做的是通过调用方法而不传递任何参数来返回Type。

我失败的部分是试图将我的班级转换为T。

这是我的代码

private T ReturnSelectedEvent<T>() where T : BaseEvent
{
    switch (eventList)
    {
        case EventItems.Debug: return (T)((object)typeof(DebugEvent));
    }
    return (T)((object)typeof(BaseEvent));
}

我要返回的是Type,这样我就可以在Class中获得一个静态变量,而不必说我要从哪个类中获取它。 所以基本上我想说

DebugEvent.description

不必指定Class,因为我有几个不同之处。

ReturnSelectedEvent<???>().description

我的DebugEvent是BaseEvent的子级,并且通过声明其自身来隐藏BaseEvent的描述。

public class DebugEvent : BaseEvent
{
    public static new string description = "This event will fire a debug message when called";
}

我希望我能说清楚自己,并且我想做的事情是可能的。

我试图用泛型解决的麻烦是我在代码中多次调用了以下代码。

case EventItems.ToggleEventHandler: toolTip = ToggleEventHandlerEvent.description; break;
case EventItems.PlayerDamage: toolTip = PlayerDamageEvent.description; break;
case EventItems.ControlRestriction: toolTip = ControlRestrictionEvent.description; break;
case EventItems.PlayerForceMove: toolTip = PlayerForceMoveEvent.description; break;

像这样

toolTip = ReturnSelectedEvent().description;

编辑:

我将要解释的更多。

上面的系统用于菜单,基本上我有一个下拉菜单,从中可以选择一个项目。 此菜单中的选项基于一个枚举,即一个称为EventItems的枚举。

在此处输入图片说明

现在,根据我选择的内容,我希望下面的描述与之匹配。 该描述以静态字符串的形式保存在BaseEvent中,然后我在子事件中使用更好地与该事件类型匹配的子事件对其进行隐藏/“覆盖”。

现在我的想法是,我可以比较枚举,并根据枚举返回相应的类型,以便设置适当的描述。 然后,我计划以后再使用相同的方法。 以下是我目前所陷入的混乱,我希望有办法清除它

if (GUILayout.Button("Add to end"))
                    {
                        switch (eventList)
                        {
                            case EventItems.Debug: AddObject<DebugEvent>(); break;
                            case EventItems.Sound: AddObject<SoundEvent>(); break;
                            case EventItems.ToggleEventHandler: AddObject<ToggleEventHandlerEvent>(); break;
                            case EventItems.PlayerDamage: AddObject<PlayerDamageEvent>(); break;
                            case EventItems.ControlRestriction: AddObject<ControlRestrictionEvent>(); break;
                            case EventItems.PlayerForceMove: AddObject<PlayerForceMoveEvent>(); break;
                            case EventItems.CameraFocus: AddObject<CameraFocusEvent>(); break;
                            case EventItems.CameraState: AddObject<CameraStateEvent>(); break;
                            case EventItems.DestroyObject: AddObject<DestroyObjectEvent>(); break;
                            case EventItems.PlayerMoveState: AddObject<PlayerMoveStateEvent>(); break;
                        }
                    }
                    if (GUILayout.Button("Insert before"))
                    {
                        switch (eventList)
                        {
                            case EventItems.Debug: InsertObject<DebugEvent>(loc); break;
                            case EventItems.Sound: InsertObject<SoundEvent>(loc); break;
                            case EventItems.ToggleEventHandler: InsertObject<ToggleEventHandlerEvent>(loc); break;
                            case EventItems.PlayerDamage: InsertObject<PlayerDamageEvent>(loc); break;
                            case EventItems.ControlRestriction: InsertObject<ControlRestrictionEvent>(loc); break;
                            case EventItems.PlayerForceMove: InsertObject<PlayerForceMoveEvent>(loc); break;
                            case EventItems.CameraFocus: InsertObject<CameraFocusEvent>(loc); break;
                            case EventItems.CameraState: InsertObject<CameraStateEvent>(loc); break;
                            case EventItems.DestroyObject: InsertObject<DestroyObjectEvent>(loc); break;
                            case EventItems.PlayerMoveState: InsertObject<PlayerMoveStateEvent>(loc); break;
                        }
                    }
                    if (GUILayout.Button("Insert after"))
                    {
                        switch (eventList)
                        {
                            case EventItems.Debug: InsertObject<DebugEvent>(loc + 1); break;
                            case EventItems.Sound: InsertObject<SoundEvent>(loc + 1); break;
                            case EventItems.ToggleEventHandler: InsertObject<ToggleEventHandlerEvent>(loc + 1); break;
                            case EventItems.PlayerDamage: InsertObject<PlayerDamageEvent>(loc + 1); break;
                            case EventItems.ControlRestriction: InsertObject<ControlRestrictionEvent>(loc + 1); break;
                            case EventItems.PlayerForceMove: InsertObject<PlayerForceMoveEvent>(loc + 1); break;
                            case EventItems.CameraFocus: InsertObject<CameraFocusEvent>(loc + 1); break;
                            case EventItems.CameraState: InsertObject<CameraStateEvent>(loc + 1); break;
                            case EventItems.DestroyObject: InsertObject<DestroyObjectEvent>(loc + 1); break;
                            case EventItems.PlayerMoveState: InsertObject<PlayerMoveStateEvent>(loc + 1); break;
                        }
                        loc++;
                    }
                    if (GUILayout.Button("Replace"))
                    {
                        switch (eventList)
                        {
                            case EventItems.Debug: ReplaceObject<DebugEvent>(); break;
                            case EventItems.Sound: ReplaceObject<SoundEvent>(); break;
                            case EventItems.ToggleEventHandler: ReplaceObject<ToggleEventHandlerEvent>(); break;
                            case EventItems.PlayerDamage: ReplaceObject<PlayerDamageEvent>(); break;
                            case EventItems.ControlRestriction: ReplaceObject<ControlRestrictionEvent>(); break;
                            case EventItems.PlayerForceMove: ReplaceObject<PlayerForceMoveEvent>(); break;
                            case EventItems.CameraFocus: ReplaceObject<CameraFocusEvent>(); break;
                            case EventItems.CameraState: ReplaceObject<CameraStateEvent>(); break;
                            case EventItems.DestroyObject: ReplaceObject<DestroyObjectEvent>(); break;
                            case EventItems.PlayerMoveState: ReplaceObject<PlayerMoveStateEvent>(); break;
                        }
                        loc++;
                    }

我希望我可以将所有不同的方法切换为一个方法,这样做的目的是相同的,但是更短一些,可能看起来像这样

AddObject<ReturnSelectedEvent()>();
InsertObject<ReturnSelectedEvent(loc)>();
AddObject<ReturnSelectedEvent(loc + 1)>();

希望这可以使事情变得更清楚,并且xxObject方法也将实例化的Event添加到List。

所以我在想什么是不可能的? 如果不是,是否有其他提示可以替代此方法?

我认为您不想要类型而是T的实例。 您必须告诉您的通用方法有一个默认的构造函数:

     private T ReturnSelectedEvent<T>() where T : BaseEvent, new()
     {
        return new T();
     }

然后,如果需要,例如获取DebugEvent ,可以使用:

ReturnSelectedEvent<DebugEvent>();

如果您真的想使用模板化工厂,请给它更多逻辑。 例如,在函数中添加一些参数,如果您不在调试模式下,则可以将其切换为null。

使用泛型是不可能的。

通用方法就像占位符一样工作。 呼叫时必须填充占位符。 现在,您正在尝试将TypeBaseEvent强制转换为T类型的实例,这是完全错误的,没有任何意义。 方法签名表明该方法返回T的实例(您应在调用时传递该实例)->废话。

您尝试做的是继承静态属性 ,这是不可能的:

但是:您的EventList中有什么? 事件实例? 还是类型? 如果实例(按照定义,事件将是更多的逻辑实例),则可以执行以下操作:为事件描述或抽象属性Description创建一个非静态的Getter方法,从而解决了问题。

tooltip = eventList.GetDescription();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM