阻止将动作设置为null(私下除外)

时间:2018-12-27 04:16:25

标签: c# null action private

我试图通过只暴露我希望public用户能够玩的东西来限制错误的表面积,从而编写代码。

在这种情况下,我有一个Action用户希望public用户能够订阅或取消订阅。但是,我不希望这些用户对其他用户产生不利影响,即取消订阅EVERYBODY。

public class X
{
    public static Action a;
}

public class Mistake
{
    public void Oops()
    {
        X.a = null;
        // I just cleared ALL subscribers to X.a - not just my own subscription.
    }
}

解决此问题的一种方法是隐藏Action本身,而是提供方法来对其进行预订/取消预订:

public class X
{
    static Action _a;

    public static void SubA(Action cb) =>
        _a += cb;
    public static void UnsubA(Action cb) =>
        _a -= cb;
}

这有效-犯类似类型的错误已经很难了。但是,它比我想要的更加冗长。

提出我的问题:

是否有任何“不错” /惯用的方式允许公开X.a += ...X.a -= ...,但不允许公开X.a = null;

我尝试使用自动属性public static Action A { get; private set; },但是正如预期的那样,这阻止了公开使用+=-=

我怀疑可能存在一种在X.a周围放置换行属性的方法,该属性在value == null时不会使设置器抛出/不执行任何操作,但是即使这样做有效,我仍然认为它仍然令人讨厌。 / p>

如果Action无法做到这一点,但是事件/委托(我对此知之甚少)可能会实现类似的效果,我也会对此感兴趣!

希望大家都在节日期间

1 个答案:

答案 0 :(得分:2)

可能为您服务,具体取决于您的需求

private Action _myAciton;

public event Action MyAction
{
   add => _myAciton += value;
   remove => _myAciton -= value;
} 

...

MyAction += () => Console.WriteLine("test1");
MyAction += () => Console.WriteLine("test2");
MyAction += null;
//MyAction = null // compiler error;

...

_myAciton.Invoke();
_myAciton = null;

输出

test1
test2

对于编译器,Event和Delegate有很多共同点,使用event关键字,并且上述模式限制了分配null的能力,还存在一些细微的其他差异,但是请尝试寻找一些信誉良好的来源。


其他资源

有关活动和代表的详细说明,给整个家庭带来很多乐趣

  • Delegates and Events

    •   

      事件关键字

           

      event关键字向编译器指示委托可以是   仅由定义类调用,其他类可以   仅使用来订阅和退订委托   分别使用+ =和-=运算符。

  • How to: Implement Custom Event Accessors (C# Programming Guide)

    •   

      事件是一种特殊的多播委托,只能是   从在其内声明的类中调用。客户端代码   通过提供对方法的引用来订阅事件   触发事件时应调用。这些方法被添加到   通过事件访问器访问委托的调用列表,类似于   属性访问器,除了事件访问器名为add和   删除。

  • add (C# Reference)

    •   

      add上下文关键字用于定义自定义事件访问器   当客户端代码订阅您的事件时调用。如果你   提供自定义添加访问器,还必须提供删除访问器。

  • Delegates and Events (C# in Depth) Jon Skeet