如何创建支持任意参数的泛型委托?解决方法组转换错误
问题分析与解决方案
错误原因
你定义的Callback委托签名是void (params object[]),但DamageTarget的签名是void (Collider[]),两者并不兼容。params object[]只是允许你传入多个参数的语法糖,实际委托的参数类型是object[],而DamageTarget需要的是Collider[]——编译器无法自动将方法组转换为签名不匹配的委托,因此报错。
实现适配任意函数的泛型委托
方案1:使用.NET内置泛型委托Action<T>
直接利用框架自带的泛型委托,无需自定义Callback,可以完美匹配不同参数类型的函数:
// 保留你的DamageTarget方法 internal static void DamageTarget(Collider[] targets) { foreach (Collider target in targets) { EnemyHurtTest enemyScript = GetScript<EnemyHurtTest>(target); enemyScript.Damage(); } } // 修改ApplySphereZoneDamage,使用Action<Collider[]>作为参数 internal static void ApplySphereZoneDamage(Vector3 origin, float radius, LayerMask mask, string[] tags, Action<Collider[]> action) { List<Collider> targets = Physics.OverlapSphere(origin, radius, mask, QueryTriggerInteraction.Collide) .ToList() .FindAll(col => !HasTags(col, tags)); if (targets.Count == 0) return; // 将List转换为Collider[],匹配DamageTarget的参数类型 action(targets.ToArray()); } // 调用方式不变,此时签名完全匹配 ApplySphereZoneDamage(origin, radius: 2f, am.hammerMask, tags, DamageTarget);
方案2:自定义泛型委托
如果需要更贴合业务的委托命名,可以自定义泛型委托:
// 自定义泛型委托,适配任意单参数函数 internal delegate void Callback<T>(T parameter); internal static void DamageTarget(Collider[] targets) { foreach (Collider target in targets) { EnemyHurtTest enemyScript = GetScript<EnemyHurtTest>(target); enemyScript.Damage(); } } // 使用自定义泛型委托作为参数 internal static void ApplySphereZoneDamage(Vector3 origin, float radius, LayerMask mask, string[] tags, Callback<Collider[]> action) { List<Collider> targets = Physics.OverlapSphere(origin, radius, mask, QueryTriggerInteraction.Collide) .ToList() .FindAll(col => !HasTags(col, tags)); if (targets.Count == 0) return; action(targets.ToArray()); } // 调用方式不变 ApplySphereZoneDamage(origin, radius: 2f, am.hammerMask, tags, DamageTarget);
适配多参数函数
如果需要支持带多个参数的函数,只需对应使用Action<T1,T2>、Action<T1,T2,T3>等内置泛型委托,或自定义对应参数数量的泛型委托即可。比如针对void HealTarget(GameObject target, int amount)这样的方法,就可以用Action<GameObject, int>作为参数类型。
内容的提问来源于stack exchange,提问作者Benjamin A
相关产品推荐
相关产品推荐

