2

我在尝试从另一个类中引发类型实现接口(事件所在)的对象的事件时遇到问题。

这是我的代码:

IBaseForm接口

public interface IBaseForm
{
    event EventHandler AfterValidation;
}

实现接口 IBaseForm的 Form

public partial class ContactForm : IBaseForm
{
    //Code ...

    public event EventHandler AfterValidation;
}

我的控制器:发生错误的地方

错误信息 :

AfterValidation 事件只能出现在 += 或 -= 的左侧(除非从 IBaseForm 类型中使用)

public class MyController
{
    public IBaseForm CurrentForm { get; set; }

    protected void Validation()
    {
        //Code ....

        //Here where the error occurs
        if(CurrentForm.AfterValidation != null)
            CurrentForm.AfterValidation(this, new EventArgs());
    }
}

提前致谢

4

2 回答 2

3

您不能从定义类之外引发事件。

您需要Raise()在界面上创建一个方法:

public interface IBaseForm
{
    event EventHandler AfterValidation;

    void RaiseAfterValidation();
}

public class ContactForm : IBaseForm
{
    public event EventHandler AfterValidation;

    public void RaiseAfterValidation()
    {
        if (AfterValidation != null)
            AfterValidation(this, new EventArgs());
    }
}

在你的控制器中:

protected void Validation()
{
    CurrentForm.RaiseAfterValidation();
}

但是,如果您想从定义类之外触发事件,这通常是一种设计气味……通常在IBaseForm实现中应该有一些触发事件的逻辑。

于 2012-08-22T14:56:16.677 回答
1

事件本质上是.NET 中的一种结构,它标识两种方法——一种方法add和一种remove方法;每个都接受一个委托作为参数。

尽管事件通常与将传入的委托组合类型的字段或从中删除传入的委托的方法一起使用MulticastDelegate,但这是一个实现细节。虽然创建事件的正常目的是让其他代码传入他们希望在某些情况下调用的委托,但 .NET 中的事件机制并不关心传入的委托做了什么(如果有的话)。

在某些情况下,与事件关联add的方法和方法简单地丢弃传入的委托可能是完全合法和合乎逻辑的。remove例如,一个不可变的集合类型可能会实现IObservableCollection(以便于与例如应该自动更新以显示当前集合状态的控件一起使用),但丢弃传递给更新通知事件的任何委托。如果集合永远不会被更新,它就永远不需要使用订阅者列表,因此它没有理由保留一个。

因为不要求事件必须对传入的委托执行任何操作,所以 .NET 事件本身不可能提供除了公开addremove方法之外的任何功能。

尽管 .NET 中事件类型的描述符包括一个属性,该属性可以指定除了addremove之外的raise 方法,但该功能在实践中从未使用过。.NET 的初步设计可能打算使用它,并且删除类型的任何成员可能会在某些极端情况下(例如反序列化)导致兼容性问题,但在这些问题之外,该属性也可能不存在。

于 2012-08-22T15:21:02.983 回答