C#公开具有属性的事件

时间:2018-12-21 14:47:15

标签: c# events properties

我需要使用其他类的属性公开类实例的事件。

如果我公开了在MyClass中定义的事件和在同一MyClass中定义的属性,以便该事件像备用字段一样工作,那么一切都很好:

private event EventHandler<EventArgs> _somethingHappened;
public EventHandler<EventArgs> SomethingHappened
{
     get => _somethingHappened;
}

听起来可能很奇怪,但出于某些原因可能很有用。

但是,如果我以相同的方式公开AnotherClass中定义的事件,则该AnotherClass的实例可以访问该事件,如下所示:

public EventHandler<EventArgs> SomethingStarted
{
    get => Instance.Started;
}

其中Instance是该AnotherClass的实例,而Instance.StartedAnotherClass中的定义如下:

public event EventHandler<EventArgs> Started;

然后我收到错误消息:“该事件只能出现在左侧”。

我不明白为什么允许第一种情况而不允许第二种情况,尽管它们看起来非常相似。

2 个答案:

答案 0 :(得分:2)

  

我需要使用其他类的属性公开类实例的事件。

您不应以这种方式使用事件。事件应始终显示为event
您可以做的是通过您自己的班级公开其他班级的事件:

public event EventHandler<EventArgs> SomethingHappened
{
    add => Instance.Started += value;
    remove => Instance.Started -= value;
}

通过这种方式,订阅者实际上将订阅Instance的事件。您可以将其包装为方法,然后重新触发事件以更改sender

答案 1 :(得分:1)

事件既没有getter也没有setter,它们仅具有addremove访问器,因此它们不能用作属性。

通过代码get => Instance.Started,您正在尝试获取 Instance.Started的值,但是没有吸气剂。

您可以做的是使SomethingStarted成为一个事件,并覆盖addremove访问器,以将值转发到Instance.Started事件:

public event EventHandler<EventArgs> SomethingStarted
{
    add => Instance.Started += value;
    remove => Instance.Started -= value;
}

通过这种方式,对SomethingStarted的任何订阅都将被“重定向”到Instance.Started,而不会导致事件被重新触发

在内部,这将被翻译为类似的内容:

public void add_SomethingStarted(EventHandler<EventArgs> eventHandler) {
    Instance.add_Started(eventHandler);
}

public void remove_SomethingStarted(EventHandler<EventArgs> eventHandler) {
    Instance.remove_Started(eventHandler);
}