我想拥有EventWaitHandle对象(例如,ManualResetEvent),它只能从一个地方设置/重置,但可以从多个地方等待(使用WaitOne())。换句话说,我想只有一个类可以设置/重置它,而所有其他类都可以调用它上面的WaitOne()。它有点像常规"只读"属性:
private string MyReadOnlyText {get; private set;}
仅适用于ManualResetEvent中的特定方法。但不是:
private ManualResetEvent MyEvent {get; private set;}
当然,这不会起作用,因为虽然只有所有者类可以实例化此属性,但任何其他外部对象都可以使用MyEvent.Set / MyEvent.Reset()更改它。
这样的事情是否可能?这样做的目的是防止应用程序中的任意对象操纵等待句柄状态,并确保只能从一个地方完成此操作。
答案 0 :(得分:2)
在某种程度上,这似乎可以通过惯例来解决,即只是规定应该考虑句柄"只读"消费者。通过源代码的简单grep应该有助于确保防止歹徒。
仅支持真实的"概念的支持有限。 event,如果仅将对象公开为WaitHandle
。 WaitHandle
个实例没有Set()
方法,因此有助于提醒来电者不要弄乱它。
当然,调用者仍然可以将其转换为实际类型,WaitHandle
中仍有静态方法允许操作。所以这不是100%的保证。但它会有所帮助(并且在您进行代码审计时为grep提供更多独特的模式)。
最后,"包装"评论中提到的方法也可以起作用。这是最强大的,并且是任何类型的限制访问除了所有者对象之外的成员的相对常见的模式"。
如果调用者与特权代码位于不同的程序集中,那么最简单的方法是创建隐藏的内容" internal"和公共的东西"公众。如果它们在同一个程序集中,那么如果你可以将隐藏的成员与特权代码放在同一个类中,那么它们当然可以是该类的私有。
通常,您希望将特殊辅助功能对象封装为单独的类,同时仍授予对某个特定类的特权访问权限,并限制其他所有人的访问权限。在这种情况下,您可以使用嵌套类来实现这种分离,外部类包含特权代码,嵌套类包含隐藏代码。
此方法的一个版本使用基础/子类设计,其中基类具有公共成员,子类具有隐藏代码:
class A
{
public class B
{
protected ManualResetEvent _event = new ManualResetEvent(false);
public void Wait() { _event.Wait(); }
}
private class C : B
{
public void Set() { _event.Set(); }
}
public B GetAnInstanceofB() { return new C(); }
private void DoSomethingWithB(B b) { ((C)b).Set(); }
}
现在,调用者可以在返回的实例上调用B.Wait()
,但他们无法转换为类型C
来访问Set()
方法。但请注意,允许类A
中的代码(因为它可以将类型转换为C
)。
请注意,类B
本身不需要嵌套。只需C
。
此主题的另一个变体是声明一个只包含公共方法的接口,然后拥有该接口的单个实现者。同样,实现类将私有嵌套到特权代码,而接口可以嵌套或不嵌套。
最后请注意,所有这些都是代码可靠性和维护的问题。当然,代码总是可以使用反射来检查和访问它想要的任何类型的任何部分。
在一天结束时,您必须考虑代码的受众。如果它是一个小团队并且代码对于单个项目来说都是完全独立的,那么告诉所有人可能已经足够了#34;你可以等待,但不要笨蛋这个事件"。在一个更大的环境中,也许有几个团队一起处理几个相关的项目,但仍然基本上是一个独立的单元,使用WaitHandle
可能就足够了。如果你正在编写一个你想要广泛使用的库,那么封装和私有成员和类是一个很好的工具。 :)