簡體   English   中英

將泛型與基類一起使用時的重載方法

[英]Overloading methods while using Generics with base classes

我有以下課程:

public abstract class Gear<T> : ScriptableObject, IGear { ... }

public class Armor : Gear<ArmorStatsLevel> { ... }

public class Weapon : Gear<WeaponStatsLevel> { ... }

現在,我可以使用以下方法列出實例:

public abstract class WidgetListArmor {

    public void ActionSelected(Armor gear) {
        if (...) GameSession.Equip(gear);
    }
}

public abstract class WidgetListWeapon {

    public void ActionSelected(Weapon gear) {
        if (...) GameSession.Equip(gear);
    }
}

因為這是多余的,所以我想到了將其全部轉移到基本類:

public abstract class WidgetListGear<T> : MonoBehaviour {

    public void ActionSelected(T gear) {
        if (...) GameSession.Equip(gear);
    }
}

public class WidgetListArmors  : WidgetListGear<Armor> { ... }

public class WidgetListWeapons : WidgetListGear<Weapon> { ... }

盡管這看起來更干凈,但我現在遇到了一個新問題。 因為T是泛型, GameSession.Equip不能使gear超載。

我是否選擇了錯誤的模式來組織代碼? 我是否從泛型中缺少可以執行此操作的內容?

UPDATE

這是GameSession簽名:

public class GameSession {
    public static bool Equip(Armor armor);
    public static bool Equip(Weapon weapon);
}

使Weapon and Armor實現名為IGear的接口,例如:

public interface IGear 
{ }

public class Weapon : IGear
{
    //snip
}

public class Armor : IGear
{
    //snip
}

將通用類型限制為IGear

public abstract class WidgetListGear<T> : MonoBehaviour
    where T : IGear
{

    public void ActionSelected(T gear) {
        if (...) GameSession.Equip(gear);
    }
}

並使GameSession.EquipIGear作為參數類型。

您正在尋找的是動態調度。 我建議您嘗試以下方法:

GameSession.Equip((dynamic)gear);

但是,我認為這不是最好的主意,因為您已經嘗試在類型系統中對Game規則進行編碼,而現在您正在運行時啟動一個小型編譯器來為您執行調度。

我想向您指出埃里克·利珀特(Eric Lippert)關於該主題的文章 看來您對他的描述有類似的問題。

第4部分描述了我提供的動態方法及其缺點。 第5部分提供了一種完全不同的方法。 總的來說,我強烈建議閱讀每一部分。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM