views:

65

answers:

2

I want to add events to some built in .NET classes. For example I want to add the following events to a generic List(T):

  • ItemAdded
  • ItemRemoved
  • ListChanged
  • etc

I can think of a few ways to accomplish this, but I'm not sure which approach is best.

  1. I could use "extension events", that is, if there is such a thing or a way to use extension methods to simulate event-like functionality.
  2. I could inherit from List(T) and override the necessary methods and properties.
  3. I could inherit from List(T) and shadow the necessary methods and properties.
  4. I could create a new class that implements IList(T) and then wrap the remaining functionality of List(T) that IList(T) is missing.

Obviously option 4 is the most work, which is not a big deal if I only wanted to extend one class. However, I also want to avoid nasty side effects.

What are the advantages, disadvantages, and caveats for each approach?

Note: I'm not really concerned here with IList(T) specifically. I find myself wanting to add "extenstion events" to other classes as well.

+2  A: 

"extension events" don't exist, nor do extension properties or anything other than extension methods. Personally I'd like to see extension properties (given that they're just wrappers for functions), but I'm not sure how you could implement extension events in the static fashion that extensions require.

There is nothing stopping you from adding those events to the class itself. However, you might have more success looking at BindingList<T>, since it's more in line with the monitoring activity you appear to want to do.

Adam Robinson
+4  A: 
  1. There's no such thing as "extension events" and you can't use extension methods to simulate this: extension events can't add state to existing classes, which is what you'd require.

  2. I think you mean override rather than overload. This will work, this it's slightly clumsy - and means you couldn't use the normal ToList from LINQ etc, because then you'd just get a List<T>.

  3. Shadowing is nastier than overriding. It means that the events may or may not be raised based on how the caller is calling the method. Ick.

  4. This would be preferable, and you could add an extension method to List<T> to wrap it. One disadvantage is that if anyone else "knows about" the unwrapped collection, you won't spot changes made that way.

Have you looked at ObservableCollection<T>? Note that this will copy from a list if you provide it in the constructor, rather than wrapping the list.

Jon Skeet
4. Is the disadvantage in implementing IList(T) or in using an extension method to List(T) to wrap it? Secondly, I'm not sure how to use an extension method to List(T) to wrap it...
JRS