如何实现支持可变数量泛型参数的Event结构体?
实现支持可变参数的泛型Event结构体
要实现支持任意数量参数的Event结构体,核心思路是针对不同数量的参数定义对应的泛型结构体版本,每个版本内部存储匹配参数数量的Action<...>委托,并实现对应的操作符重载和Invoke方法。因为C#的泛型不支持可变数量的类型参数,所以需要为每个参数数量(对应Action的泛型重载)单独实现结构体。
核心实现步骤
- 为每个参数数量定义泛型结构体,内部存储对应参数数量的
Action委托。 - 重载
+和-操作符,实现委托的添加与移除(注意结构体是值类型,需返回新实例)。 - 实现匹配参数数量的
Invoke方法,安全触发委托(避免空引用异常)。
代码示例
单个参数版本
public struct Event<T> { private Action<T> _action; // 添加委托的操作符重载 public static Event<T> operator +(Event<T> e, Action<T> action) { e._action += action; return e; } // 移除委托的操作符重载 public static Event<T> operator -(Event<T> e, Action<T> action) { e._action -= action; return e; } // 触发委托的Invoke方法 public void Invoke(T arg) { _action?.Invoke(arg); } }
三个参数版本(对应你的需求示例)
public struct Event<T1, T2, T3> { private Action<T1, T2, T3> _action; public static Event<T1, T2, T3> operator +(Event<T1, T2, T3> e, Action<T1, T2, T3> action) { e._action += action; return e; } public static Event<T1, T2, T3> operator -(Event<T1, T2, T3> e, Action<T1, T2, T3> action) { e._action -= action; return e; } public void Invoke(T1 arg1, T2 arg2, T3 arg3) { _action?.Invoke(arg1, arg2, arg3); } }
使用示例
// 声明对应Action<int, string, bool>的Event实例 Event<int, string, bool> VictoryEvent; // 添加委托 VictoryEvent += (score, message, isCritical) => { Console.WriteLine($"胜利!分数:{score},消息:{message},是否关键胜利:{isCritical}"); }; // 触发委托 VictoryEvent.Invoke(1000, "击败最终BOSS", true);
扩展说明
- 可以按照相同的逻辑扩展到更多参数(
Action最多支持16个泛型参数),比如实现Event<T1,T2>、Event<T1,T2,T3,T4>等版本。 - 结构体是值类型,所以每次使用
+=或-=时,都会创建一个新的结构体实例并赋值给原变量,这是值类型的特性,确保操作的正确性。 - 使用
_action?.Invoke(...)可以避免委托为空时的空引用异常。
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

