You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 22:15:23