C#中如何判断Action的Invoke被触发及对应调用的实例对象?
解决方案
核心原理
C# 中的多播委托内置GetInvocationList()方法,可获取所有注册到该委托的子委托条目,每个条目包含两个关键属性:
Method:存储注册方法的完整反射信息,可用于校验当前是否为目标方法myMethodTarget:存储方法所属的实例对象(如果是静态方法则该属性为null)
实现方案1:触发侧遍历调用列表校验
你可以不直接调用Event.Invoke(),改为手动遍历所有子委托逐个触发,同时做校验和实例识别,修改后的DoInvokeTest代码如下:
public void DoInvokeTest() { if (Event == null) return; // 获取所有注册的委托条目 var invocationList = Event.GetInvocationList(); foreach (Delegate del in invocationList) { // 校验是否为TheClass类定义的myMethod方法,避免同名方法误判 if (del.Method.Name == nameof(myMethod) && del.Method.DeclaringType == typeof(TheClass)) { // 提取方法所属的实例 var targetInstance = del.Target as TheClass; // 此处可自定义校验逻辑,比如判断是否为目标实例theclassObj Console.WriteLine($"待调用myMethod的实例哈希值:{targetInstance.GetHashCode()}"); // 执行当前委托 del.DynamicInvoke(); // 标记方法已调用完成 Console.WriteLine($"实例[{targetInstance.GetHashCode()}]的myMethod已执行完成"); } else { // 其他注册方法直接执行 del.DynamicInvoke(); } } }
实现方案2:方法内部直接获取所属实例
如果你不需要在触发侧做逻辑,只需要确认方法被调用时的所属实例,直接在myMethod内部通过this关键字即可获取:
public void myMethod() { // this即为当前方法所属的TheClass实例 Console.WriteLine($"myMethod已被调用,所属实例哈希值:{this.GetHashCode()}"); // 此处也可以直接加日志或者打标记,确认方法执行 }
注意事项
- 不要向事件注册匿名方法/Lambda表达式,这类方法的Target为编译器自动生成的闭包对象,无法直接匹配到业务实例
- 静态事件的注册方法需要手动解绑,否则会导致实例无法被GC回收,引发内存泄漏
内容的提问来源于stack exchange,提问作者orochi
相关产品推荐
相关产品推荐

