根据第一个参数对函数的第二个参数进行类型检查

时间:2018-08-18 03:01:48

标签: c# unity3d

我有一个将动作注册到游戏中特定触发器的功能。例如:

Triggers.RegisterTriggeredEvent(Trigger.OnPlayerDamage, playerDamageHandler);

我希望playerDamageHandler为特定类型,例如:

void PlayerDamageHandler(Player damaged, DamageType type);

是否有更好的方法,然后根据键值对字典(例如[OnPlayerDamage:ActionType])对操作进行运行时类型检查?有没有一种方法可以静态检查传递给RegisterTrigger的函数的类型?

使用事件无法完成此操作,因为触发器的解决顺序取决于玩家的输入。将触发器注册到事件中,然后按照游戏规则确定的特定顺序进行解析。

1 个答案:

答案 0 :(得分:1)

我认为有可能。只需为每个事件类型创建一个具有一个实例的Event<THandler>类即可。类型参数THandler是处理事件的代表的类型。

// Represents a single event type, e.g. PlayerDamage, PlayerDeath, etc.
public class Event<THandler> where THandler : Delegate { }

public delegate void PlayerDamageHandler(Player player, DamageType type);
public delegate void PlayerDeathHandler(Player player, DeathReason reason);

public static class Events
{
    public static Event<PlayerDamageHandler> OnPlayerDamage = new Event<PlayerDamageHandler>();
    public static Event<PlayerDeathHandler> OnPlayerDeath = new Event<PlayerDeathHandler>();
}

然后添加用于注册处理程序的方法,

public void RegisterTriggeredEvent<THandler>(Event<THandler> @event, THandler handler) 
    where THandler : Delegate 
{ 
    ... 
}

您可以这样使用它:

RegisterTriggeredEvent(Events.OnPlayerDamage, playerDamageHandler);

如果处理程序的参数类型错误,例如:

RegisterTriggeredEvent(Events.OnPlayerDamage, (Player p, int foo) => { ... });

产生编译时错误:

  

参数2声明为类型'int',但应为'DamageType'

也许您可以将处理程序列表和RegisterTriggeredEvent方法直接放入Event类中。

注意:Delegate通用约束是在C#7.3中添加的,我不确定Unity是否支持它。