为什么TextBox.Click事件只能出现在+ =或 - =的左侧

时间:2012-10-07 11:43:02

标签: c# event-handling extension-methods

我正在尝试编写EventHandler的扩展方法,如下所示:

public static class MyExtensions
{
    public static void Add(this EventHandler handler, EventHandler next)
    {
        //Do something
    }
}

它适用于我的活动,例如:

public event EventHandler MyEvent

我可以毫无问题地使用我的扩展程序:

MyEvent.Add((x, y) => { /* do something */ });

但是当我想将它应用于TextBox的Click事件时,我收到一个编译错误:

  

错误CS0079:

     

事件System.Windows.Forms.TextBoxBase.Click只能出现在+=-=

的左侧

让我感到困惑的是,Click事件与MyEvent没有任何不同,那么为什么它会有约束?

2 个答案:

答案 0 :(得分:4)

如果Add方法是在同一个类中的调用MyEvent,那么它可能正常工作。

但是,Click方法是在不同的类中定义的,而不是从您调用Add的方法。这就是为什么它不起作用。

.NET框架不允许在定义它的类之外直接修改事件,否则一些胭脂代码可能会删除任何类的所有事件处理程序。

这是我能提出的最好的扩展方法,可以帮助你做你想做的事情:

public static Action Add<TDelegate>(
    this TDelegate handler, 
    Action<TDelegate> addHandler, 
    Action<TDelegate> removeHandler)
{
    addHandler(handler);
    return () => removeHandler(handler);
} 

你可以像这样使用它:

var bar = new Bar();

EventHandler handler = (s, e) =>
{
    Console.WriteLine("MyEvent!");
};

var cleanup = handler.Add(h => bar.MyEvent +=h, h => bar.MyEvent -=h);
bar.Raise();
bar.Raise();
cleanup();

cleanup操作用于在不需要时删除事件处理程序。

为简单起见,我遗漏了所有必需的空检查代码。你必须把它们放在适当的地方。

答案 1 :(得分:1)

两者之间存在差异。一个简单的例子可以证明它:

private EventHandler foodel;
public event EventHandler foo {
    add { foodel += value; }
    remove { foodel -= value; }
}
public event EventHandler bar;

...
foo.Add((s, e) => { });   // CS0079
bar.Add((s, e) => { });   // No error

删除访问者,代码编译干净。

我将继续说你无意中利用编译器错误。它应该拒绝对没有访问器声明的事件使用扩展方法。微软将修复这个漏洞的几率非常低,这已经持续了很长时间。但最好的解决方法是删除扩展方法。