C#内部委托和公共事件

时间:2010-12-10 13:04:36

标签: c# events delegates

我目前正在开发一个独立于任何应用程序的微小技术框架。业务代码只是引用此框架。

根据这篇文章:http://msdn.microsoft.com/en-us/library/5z57dxz2.aspx(例2),我们需要为自定义事件提供委托。

问题是,任何人都可以调用我的处理程序(然后引发事件),即使在我的业务代码中,这对我来说也不符合逻辑,那么使用仅限委托来提升自定义事件的最佳方法是什么“内部”而非“公开”?

感谢您的帮助。

5 个答案:

答案 0 :(得分:6)

我不确定我是否正确。我认为,如果您为自定义活动提供公开Delegate类型,那么任何人都可以提升该活动。

嗯,事实并非如此。只有定义该自定义事件的类才能引发它。如果这是您的问题,请不要担心。

答案 1 :(得分:3)

不正确。不允许在事件所属的类之外调用事件。其他人只能在您的活动中使用+=-=运算符。只有在课堂上,您才能调用该事件。这是事件和普通代表之间的区别。那就是:

public Data
{
   public event EventHandler OnSave
   public EventHandler OnLoad;

   private void Load()
   {
       if (OnLoad!=null) OnLoad();  
       //other operations
   }
   private void Save()
   {
       if (OnSave!=null) OnSave();  
       //other operations
   }
}

在课外:

Data data = new Data();
data.OnLoad += (s,e) => {}; 
data.OnSave += (s,e) => {};
data.OnLoad = (s,e)=>{}; 
//data.OnSave = (s,e)=>{};  //invalid
data.OnLoad();
//data.OnSave();  //invalid

答案 2 :(得分:2)

委托只是一个描述事件“签名”的类型声明。这必须是公开的。要实际调用您的事件,您通常会实现一个名为OnEvent的方法(您可以用EventClick替换Closed或其他任何描述您事件的方法。此方法应该是您班级中的私人(或受保护)。

您不能使用比事件“不可见”的委托来声明事件。

答案 3 :(得分:1)

一种方法:

创建一个手动订阅所需委托的方法,而不是公共事件,并将它们存储在“private List _delegates”字段中。

然后,从“内部”开始,在你想要的时候给他们打电话。

public class Framework 
{
    public delegate void Method();
    public void AttachEvent(Method M)
    {
         _methods.Add(M);
    }
    private List<Method> _methods;
    private FireMethods() 
    {
         _methods.Foreach(x=>x.Invoke());
    }
}

或者,您可以接受他们不公开Invoke()能够发生的事件的“按设计”功能。

:)

答案 4 :(得分:1)

  

问题是,任何人都可以调用我的处理程序(然后引发事件),即使在我的商业代码

中也是如此

事实并非如此。您声明一个事件如下:

public event FooEventHandler Foo;

外部代码可以对事件做的唯一事情是订阅它(+=),或者取消订阅它(-=)。它无法访问由编译器作为私有字段生成的实际委托。换句话说,此代码无效:

SomeClass x = new SomeClass();
x.Foo(x, new FooEventArgs()); // compilation error here

不要忘记事件实际上是一对方法(添加和删除)。编译器将事件声明重写为以下行:

private FooEventHandler _foo;

public event FooEventHandler Foo
{
    add { _foo += value; }
    remove { _foo -= value; }
}

(生成的代码实际上有点复杂,有一些锁定以确保线程安全)

如您所见,_foo字段是私有的,因此客户端代码无法访问它。只能访问活动的addremove访问者。