簡體   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