I am writing a collection that accepts a time parameter, the purpose is that after that specified amount of time have passed the element won't be present in the collection.

I want the user of this collection to be able to act when an item is removed from the collection under this circumstance. I have two different ways of achieving this, but I am unsure which I should take. Both approaches feels different, but the end result is pretty much the same.

I am asking this question since I may not notice a small (or large) difference between the two and I was hoping to get guidance.

Approach A: Have an event such as OnRemovalDueToTimeout which expects some function that receive an element (e.g void foo(T removedElement)). upon removal I would raise the event

Approach B: Receive a delegate with the same signature as above and call that delegate when an element times out.

  • How many listeners do you expect? – Dan Pichelman Feb 19 '17 at 16:43
  • @DanPichelman - I wrote this class having in mind I was expecting only one listener – Belgi Feb 19 '17 at 16:47

Lucky for you, all the code you need already exists in .NET Framework. It's called ObservableCollection<T>, and it consists of a collection class which has the event CollectionChanged which is raised when an item is added, removed or changed.

All you have to do is to inherit from this class, and implement the timer logic. When the timer expires, it simply removes an element; .NET Framework will handle the events part.

If you want the event to be raised only when the timer elapses, and not when any element is removed from the collection, then you need your own class. Since most .NET developers have already used ObservableCollection<T>, for the sake of simplicity, use the same interface. The event name would be different—especially to indicate that it's not raised when any element is removed—but the general interface should look the same. Note that the source code of ObservableCollection<T> would probably help you drafting your own class.

As for the general case of events vs. delegates:

  • In languages such as JavaScript, the delegates (callbacks) are the standard way of informing the caller of something which happens in the future.

  • In languages such as C#, the usual way is to use events. Although technically, both are very similar, .NET Framework and many C# applications show a preference for the events, so according to POLA, events would be a good choice.

  • Thank you for your answer. The issue is not the implementation - I am basing myself on .Net collections such as List<T>. I also want a simpler API then the one provided by Observable collection, I want notifications to be sent only in one particular event. The issue is about how to notify and emphasis about the use by consuming code – Belgi Feb 19 '17 at 16:50
  • @Belgi: “I also want a simpler API then the one provided by Observable collection”: to make it simpler for others, reuse existent interfaces and paradigms. Most .NET developers know how to use ObservableCollection<T>. You won't make their lives simpler by using a radically different approach in your class. – Arseni Mourzenko Feb 19 '17 at 17:24
  • @Belgi: “I want notifications to be sent only in one particular event”: in other words, there are other situations where elements are removed from the sequence, but you don't want the event to be raised in those cases. Valid point. Then instead of inheriting from ObservableCollection<T>, simply mimic its behavior (and interface). This also means using events, and not callbacks. – Arseni Mourzenko Feb 19 '17 at 17:26

Generally, passing in a delegate is a better approach.

Events introduce lifetime issues (when this object dies, do I need to unregister the event handler?). Events require null checks for each call, delegates can be checked in the constructor. Events complicate error handling, since each handler needs to behave so that they don't interrupt the event for other handler; since delegates are passed in, that becomes the responsibility of the caller.

In short, events introduce a bit of complexity that isn't particularly useful outside of a very specific scenario.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.