C#通用自取消订阅委托实现遇问题:为何静态方法调用不生效?
问题描述
本人对C#术语了解有限,此前找到可正常运行的自取消订阅委托代码:
private delegate void V; private V delVoid; private void SelfUnsubscribeDelVoid() { void Unsubscriber() { // 执行操作 delVoid -= Unsubscriber; } delVoid += Unsubscriber; }
由于需要使用多个此类委托,我编写了一个静态通用方法以复用逻辑,代码如下:
public static class Delegates { public delegate void V(); public static void SelfUnsubscribeDelVoid(V theDelegate, V functionToExecute) { void Unsubscriber() { functionToExecute(); theDelegate -= Unsubscriber; } theDelegate += Unsubscriber; } } public class Caller { private Delegates.V OnDoingSomething; public void FunctionA() { Delegates.SelfUnsubscribeDelVoid(OnDoingSomething, FunctionB); OnDoingSomething(); // FunctionB未被触发 } private void FunctionB() { // 执行操作 } }
但调用时FunctionB未被触发,推测OnDoingSomething与输入参数theDelegate未正确关联。请问代码是否存在错误?该实现思路是否可行?或是此需求根本无法实现?
问题分析与解决
代码错误原因
C#里委托是按值传递的,你在SelfUnsubscribeDelVoid方法中操作的theDelegate只是外部OnDoingSomething的副本。方法里执行theDelegate += Unsubscriber,只是给这个副本添加了订阅,外部的OnDoingSomething完全没变化,所以调用时自然不会触发FunctionB。
修正方案
要让方法能修改外部的委托实例,需要用ref关键字传递参数,这样方法操作的就是原始委托的引用。修改后的静态类代码如下:
public static class Delegates { public delegate void V(); public static void SelfUnsubscribeDelVoid(ref V theDelegate, V functionToExecute) { void Unsubscriber() { functionToExecute(); theDelegate -= Unsubscriber; } theDelegate += Unsubscriber; } }
调用时也要加上ref关键字:
public void FunctionA() { Delegates.SelfUnsubscribeDelVoid(ref OnDoingSomething, FunctionB); OnDoingSomething(); // 此时FunctionB会被正常触发 }
实现思路可行性
这个思路完全可行,通过ref传递委托,就能在静态方法里统一处理自取消订阅的逻辑,避免重复编写相同代码。需要注意的是,多线程场景下要额外考虑线程安全,防止委托被并发修改引发问题。
内容的提问来源于stack exchange,提问作者Solihin
相关产品推荐
相关产品推荐

