Unfortunately, this code does not compile. A Compiler Error CS0066 appears:

'EventProvider.MyEvent': event must be of a delegate type

Basically, what I need is a property that has add and remove accessors instead of get and set. I think the only way to have that is using the event keyword. I know that one obvious alternative is to declare two methods that would do the adding and removing, but I want to avoid that too.

Does anybody knows if there is a nice solution this problem? I wonder if there is any way to cheat the compiler to accept a non-delegate type as an event. A custom attribute, perhaps.

There is no problem with regular events. The problem is with regular delegates. They keep strong references to the target object. I implemented a class that works like a delegate, but uses a WeakReference internally. If I only could use it in an event property, the solution would be perfect. And that's only one of the possibilities. I know that it may sound like reinventing the wheel, but I'm quite sure it isn't.
–
jpbochiJul 15 '09 at 21:46

If you're going to use your own event-style architecture, I would recommend patterning it after IObservable rather than the delegate combine/remove pattern. The latter creates unavoidable ambiguities if an events get subscribed/unsubscribed more than once, requires an event subscriber to keep a strong reference to the publisher to allow for unsubscription, even in cases where no strong reference would otherwise be required, makes it hard to keep a list of necessary unsubscriptions, etc. The former avoids all those problems.
–
supercatNov 19 '12 at 23:12

4 Answers
4

If you want to be able to add and remove CustomEvent objects from the event (instead of regular delegates), there are two options:

Make an implicit cast from ICustomEvent to EventHandler (or some other delegate) that returns an instance method of ICustomEvent (probably Invoke), then use the Target property of the delegate to get the original ICustomEvent in the add and remove accessors.

About the implicit cast option: it's an interesting idea. I see that it's possible to hide a CustomEvent inside a delegate. Maybe, I could mark the method with a custom attribute in order to differentiate a CustomEvent from a Delegate. I'll try to code it. thanks!
–
jpbochiJul 16 '09 at 14:26

About the writable property option: I have considered it in the past, but I dislike it for one good reason. Any external code would be able to overwrite the current CustomEvent. I want a solution that provides the same pattern that regular events do: user code is only able to add/remove the handlers it knows. Invoking the event and reading the current handlers should not be allowed.
–
jpbochiJul 16 '09 at 16:08

@1st: What would be the point of a custom attribute? I don't see what you're saying there.
–
SLaksJul 16 '09 at 16:39

1st) Thanks for your suggestion, but it's 100% exactly to a regular event. That's not what I'm looking for; 2nd) I want to raise the event from the EventProvider class. I don't think raising events from external classes is a good idea in any situation; 3rd) Thanks for your links, but I already knew both of them. My code, by the way, is strongly inspired by the codeproject article you mentioned.
–
jpbochiJul 15 '09 at 21:57

If the first one isn't what you want to do, what do you want? <br>To be able to add ICustomEvents?
–
SLaksJul 15 '09 at 22:06

I'm sorry, I misread your answer. You're right, I want to be able to add and remove ICustomEvent, not only EventHandler's. I fixed the question to make it clearer. (I would vote this answer up if I had enough reputation)
–
jpbochiJul 16 '09 at 13:06

So instead of having event-like add and remove methods, you can have a field or a property that can be combined by += and -= operators. Besides it encapsulates the combination logic inside your own CustomEvent class.

That's the same as the second option that SLaks proposed above. He also proposed a special treatment to avoid the possibility of overwriting the event. To be honest, I prefer his first option. I have already coded it and I'm doing some tests.
–
jpbochiJul 17 '09 at 17:00

I have to agree with you, the first option is better because you acctualy can use "regular" event handlers in addition to your custom weak event. Besides, I haven't noticed his comment about overloading the + and - operators. Sorry.
–
Carlos LothJul 17 '09 at 18:36