简体   繁体   中英

C# expose events with properties

I need to expose an event of an instance of a class using a property from a different class.

If I expose an event defined in MyClass with a property defined in the same MyClass , so that the event works like a backing field, everything is fine:

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

Could sound weird, but it might be useful for some reason.

But if I expose (in the same manner) an event defined in AnotherClass , accessed by an instance of that AnotherClass , as follows:

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

where Instance is the instance of that AnotherClass and Instance.Started is defined in AnotherClass as follows:

public event EventHandler<EventArgs> Started;

then I get the error: "The event can only appear on the left hand side".

I just don't get why the first case is allowed and the second is not, although they seem very similar.

I need to expose an event of an instance of a class using a property from a different class.

You shouldn't use events this way. Event should always be exposed as an event .
What you can do is to expose other class' event through your own class:

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

This way a subscriber will actually subscribe to the Instance 's event. You can wrap it to a method and re-fire an event to change the sender .

Events do not have getters nor setters, they only have add and remove accessors thus they cannot be used as properties.

By code get => Instance.Started you're trying to get the value of Instance.Started but there is no getter.

What you can do is make SomethingStarted also an event and override add and remove accessors to forward the value to the Instance.Started event:

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

This way any subscription to SomethingStarted would be "redirected" to Instance.Started without causing event to be re-fired .

Internally, this would be translated into something like:

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM