引发类型实现接口的对象事件

时间:2012-08-22 14:51:51

标签: c# .net events interface

尝试引发一个对象的事件时遇到问题,该对象的类型实现了一个接口(事件所在的地方)形成另一个类。

这是我的代码:

界面 IBaseForm

public interface IBaseForm
{
    event EventHandler AfterValidation;
}

实现IBaseForm接口的表单

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());
    }
}

提前致谢

2 个答案:

答案 0 :(得分: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实现中应该有一些触发事件的逻辑。

答案 1 :(得分:1)

event本质上是.NET中的一种结构,用于标识两种方法 - add方法和remove方法;每个都接受delegate作为参数。

虽然事件通常与将传入的委托组合到的方法一起使用,或者从,类型MulticastDelegate的字段中删除传入的委托,是一个实现细节。虽然在某些情况下创建事件的正常目的是让其他代码在代理中传递他们想要调用,但.NET中的事件机制不会关心什么,如果有的话,是用传入的代表完成的。

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

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

虽然.NET中 event 类型的描述符包含一个属性,除了 add raise方法 >删除,该功能从未在实践中使用过。 .NET的初步设计可能意图使用它,删除某个类型的任何成员可能会导致某些极端情况下的兼容性问题,例如反序列化,但在此类问题之外,该属性可能不会存在。