1

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.

Kenna
  • 302
  • 4
  • 15
  • 1
    If I wanted to do this I'd have an event on my own class that fired when the eventhandler on the class I was wrapping was called (I listen to the event, and I fire my own event when I detect the other event occurring) – Caius Jard Dec 21 '18 at 14:58
  • Yes, interesting solution, I didn't think about it, since I was really stuck on that error. But could "fire and re-fire an event" bring to performance inefficiency? – Kenna Dec 21 '18 at 15:02

2 Answers2

8

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);
}
Imantas
  • 1,621
  • 13
  • 19
  • Thank you for your answer. I marked this as accepted because it answers directly my question about the error. – Kenna Dec 21 '18 at 15:17
2

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.

Yeldar Kurmangaliyev
  • 33,467
  • 12
  • 59
  • 101
  • So it's more a problem of concept and correct use of the events. Thank you very much for your interesting answer, I understand events even better now. – Kenna Dec 21 '18 at 15:14