在方法中强制转换不同的子类

我想发送,接收和转换SkillEvent类的子类,并能够根据其类型在内部抓取自定义参数。


可能有许多具有不同参数的不同子类。


有没有一种方法可以避免为每种技能编写不同的方法?


class SkillEvent { float timestamp, EventType type }

class GrenadeSkillEvent : SkillEvent { Vector3 target_point}


[ClientRpc]

RpcSendSkillEvent(SkillEvent event){

    eventManager.ExecuteEvent(event);

}


ExecuteEvent(SkillEvent event){

    switch(event.type){

        case GrenadeSkillEvent : 

            GrenadeSkillEvent grenadeEvent = (GrenadeSkillEvent) event;

            float grenadeParam = event.grenadeParam;

            break;


        case OtherSkillEvent : 

            OtherSkillEvent otherEvent = (OtherSkillEvent ) event;

            string stringParam = event.stringParam;

            break;

    }

}

我认为可以这样做,但显然不行。


有没有一种方法可以避免为每种技能编写不同的方法?


编辑 :


GrenadeSkillEvent和OtherSkillEvent是SkillEvent的子级。


它们都有一个时间戳和一种类型,我认为我可能需要帮助将事件变量转换为正确的SkillEvent子类。


我的问题是,它们具有相同的方法(可以说是execute),但是每种子类都需要不同类型的参数。


例如,一个GrenadeEvent可能需要一个目标点,爆炸的大小和伤害。


一个BonusEvent可能有些HP添加到播放器。


一个TerrainEvent可以激活一个重要的目标靠近播放器等一些自定义动画


这些技能背后的所有逻辑都是相同的。


它们都有两种方法:


Simulate(SkillEvent Event) and Render(SkillEvent Event)

但是例如在GrenadeSkill中,我需要它


Simulate(GrenadeSkillEvent Event) and Render(GrenadeSkillEvent Event)

编辑2:


networkedPlayer.RpcOnSkillEvent(

    new SkillEvent[] {

        new GrenadeSkillEvent() {

            timestamp = state.timestamp,

            id = 0,

            point = target

        } 

    }

);

编辑3:


var dictionary = new Dictionary<Type, Action<SkillEvent>> {

    {

        typeof(GrenadeSkillEvent), (SkillEvent e) => {

            Debug.Log("GrenadeSkill OnConfirm point"+ ((GrenadeSkillEvent)e).point);

        }

    }

};


public override void OnConfirm(SkillEvent skillEvent) {


    if (skillEvent == null) return;


    Debug.Log(skillEvent.GetType());

    dictionary[skillEvent.GetType()](skillEvent);

}


一只斗牛犬
浏览 154回答 3
3回答

慕田峪4524236

最好的方法是在顶级类上编写通用的getter方法,SkillEvent然后在special类中重写该方法。由于您似乎需要不同的类型,因此我认为您可以使用执行您在类内部进行参数化的方法的方法这是您当前代码已发布的示例:class SkillEvent {&nbsp;&nbsp; float timestamp;&nbsp;&nbsp; EventType type ;&nbsp; public virtual void executeEvent(){ //handles the general case for the execute funciton&nbsp; &nbsp; execute(timestamp);&nbsp; }}class GrenadeSkillEvent : SkillEvent { //overriden to pass target point into event execution&nbsp; Vector3 target_point;&nbsp; public override void executeEvent(){&nbsp; &nbsp; execute(target_point);&nbsp; }}class BonusEvent : SkillEvent {&nbsp;&nbsp; int bonus_health;&nbsp; public override void executeEvent(){/overriden to pass bonus health into event&nbsp; &nbsp; execute(bonus_health);&nbsp; }}class TerrainEvent : SkillEvent {&nbsp;&nbsp; GameObject obj;&nbsp; public override void executeEvent(){//overriden to play animation before event is executed&nbsp; &nbsp; animation(obj);&nbsp; &nbsp; execute();&nbsp; }}[ClientRpc]RpcSendSkillEvent(SkillEvent event){&nbsp; &nbsp; eventManager.ExecuteEvent(event);}ExecuteEvent(SkillEvent event){&nbsp; &nbsp; event.executeEvent();}
打开App,查看更多内容
随时随地看视频慕课网APP