我试图通过只暴露我希望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
无法做到这一点,但是事件/委托(我对此知之甚少)可能会实现类似的效果,我也会对此感兴趣!
希望大家都在节日期间
答案 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的能力,还存在一些细微的其他差异,但是请尝试寻找一些信誉良好的来源。
其他资源
有关活动和代表的详细说明,给整个家庭带来很多乐趣
事件关键字
event关键字向编译器指示委托可以是 仅由定义类调用,其他类可以 仅使用来订阅和退订委托 分别使用+ =和-=运算符。
How to: Implement Custom Event Accessors (C# Programming Guide)
事件是一种特殊的多播委托,只能是 从在其内声明的类中调用。客户端代码 通过提供对方法的引用来订阅事件 触发事件时应调用。这些方法被添加到 通过事件访问器访问委托的调用列表,类似于 属性访问器,除了事件访问器名为add和 删除。
add上下文关键字用于定义自定义事件访问器 当客户端代码订阅您的事件时调用。如果你 提供自定义添加访问器,还必须提供删除访问器。