Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在一行中安全地取消订阅某个操作?_C#_Action - Fatal编程技术网

C# 如何在一行中安全地取消订阅某个操作?

C# 如何在一行中安全地取消订阅某个操作?,c#,action,C#,Action,我想知道我是否可以用一行代码安全地取消C#Action的订阅,而不必编写以下代码: if(publisher.RaiseCustomEvent != null) { publisher.RaiseCustomEvent -= HandleCustomEvent; } 一个简单的例子: public class Publisher { public Action RaiseCustomEvent; public MyClass() { } } public clas

我想知道我是否可以用一行代码安全地取消C#Action的订阅,而不必编写以下代码:

if(publisher.RaiseCustomEvent != null)
{
    publisher.RaiseCustomEvent -= HandleCustomEvent; 
}
一个简单的例子:

public class Publisher
{
    public Action RaiseCustomEvent;

    public MyClass() { }
}

public class Subscriber
{
    Publisher _publisher;
    public Subscriber()
    {
        _publisher = new Publisher();
        _publisher.RaiseCustomEvent += HandleCustomEvent;
    }

    // ...

    public void Dispose()
    {
        // DO this safely in one line
        if(_publisher.RaiseCustomEvent != null)
        {
            _publisher.RaiseCustomEvent -= HandleCustomEvent; 
        }
    }
}
如果我能用一行代码以安全的方式取消C#Action的订阅

是的,您甚至不需要空检查:

//if(publisher.RaiseCustomEvent != null)
{
    publisher.RaiseCustomEvent -= HandleCustomEvent; 
}
然后你当然可以把它清理干净。
这是空安全的,可能不是线程安全的

由于事件开始时为
null
,因此您必须能够在null委托上使用
+=
进行订阅。退订也同样适用

我甚至认为RaiseCustomEvent是
事件还是动作字段都无关紧要。但是,请明确这一点

当然,您必须确保以空安全的方式引发事件,可以使用
if(…!=null)
?.Invoke()


现在您已经发布了代码,您的
RaiseCustomEvent
是一个公共字段。这在封装方面有一些缺点。使用事件是常见的做法:

public class Publisher
{
    //public Action RaiseCustomEvent;      
    public event Action RaiseCustomEvent;              
}

这将只允许
+=
-=
,并防止使用
RaiseCustomEvent=MySingleMethod

进行覆盖。请提供一个?目前,我们不知道它在哪个类中,也不知道如何声明
RaiseCustomEvent
。。。这里的小细节可能真的很重要。谢谢!但你确定吗?Microsoft文档中说:“当所有订阅者都取消订阅某个事件时,publisher类中的事件实例设置为null。”是的,它设置为null。但是您必须能够对空值执行
+=
,否则您将永远无法开始。这同样适用于
-=
。但是,正如Jon Skeet所要求的,一定要弄清楚确切的声明。编辑您的问题。@user2000950但是,在调用委托之前,您应该检查空值。