L
Larry Lard
I want to create a class which is like a List<T>, except that whenever
a T is added, it raises an event.
Simple concept, I think, but I can't seem to find a simple execution.
Ideally I would inherit from List<T> and override an OnAdd method:
// This doesn't work
public class NotifyingList<T> : List<T>
{
public delegate void ItemAddedHandler(T item);
public event ItemAddedHandler ItemAdded;
void OnAdd(T item)
{
base.OnAdd(item);
ItemAdded(item);
}
}
But there isn't such an OnAdd method.
I could inherit from List<T> and *shadow* the Add(T) method, casting
down to the base class to do the actual adding and then raising the
event:
public class NotifyingList<T> : List<T>
{
public delegate void ItemAddedHandler(T item);
public event ItemAddedHandler ItemAdded;
new public void Add(T item)
{
((List<T>)this).Add(item);
ItemAdded(item);
}
}
But Shadowing Is Bad, and also any client of the class could:
static void Main(string[] args)
{
NotifyingList<String> foo = new NotifyingList<string>();
foo.ItemAdded += StringAdded;
foo.Add("apple");
foo.Add("banana");
// evil client!
((List<string>)foo).Add("pear");
Console.ReadLine();
}
static void StringAdded(string s)
{
Console.WriteLine(s);
}
Neatly sidestepping the event raising mechanism just by downcasting (or
is it upcasting).
I could keep a private List<T> myself, and make my public signature the
same as that of a List<T>, writing code to delegate every operation to
my private List<T>, with the addition of the event raising:
public class NotifyingList<T>
{
public delegate void ItemAddedHandler(T item);
public event ItemAddedHandler ItemAdded;
private List<T> items;
public void Add(T item)
{
items.Add(item);
ItemAdded(item);
}
public ReadOnlyCollection<T> AsReadOnly()
{
return items.AsReadOnly();
}
public int BinarySearch(T item)
{
return items.BinarySearch(item);
}
public void foo()
{
items.foo();
}
// etc
// etc
// for all 50 members
}
But this involves writing a huge amount of 'empty' code, simply to
achieve one very small end.
Thoughts?
a T is added, it raises an event.
Simple concept, I think, but I can't seem to find a simple execution.
Ideally I would inherit from List<T> and override an OnAdd method:
// This doesn't work
public class NotifyingList<T> : List<T>
{
public delegate void ItemAddedHandler(T item);
public event ItemAddedHandler ItemAdded;
void OnAdd(T item)
{
base.OnAdd(item);
ItemAdded(item);
}
}
But there isn't such an OnAdd method.
I could inherit from List<T> and *shadow* the Add(T) method, casting
down to the base class to do the actual adding and then raising the
event:
public class NotifyingList<T> : List<T>
{
public delegate void ItemAddedHandler(T item);
public event ItemAddedHandler ItemAdded;
new public void Add(T item)
{
((List<T>)this).Add(item);
ItemAdded(item);
}
}
But Shadowing Is Bad, and also any client of the class could:
static void Main(string[] args)
{
NotifyingList<String> foo = new NotifyingList<string>();
foo.ItemAdded += StringAdded;
foo.Add("apple");
foo.Add("banana");
// evil client!
((List<string>)foo).Add("pear");
Console.ReadLine();
}
static void StringAdded(string s)
{
Console.WriteLine(s);
}
Neatly sidestepping the event raising mechanism just by downcasting (or
is it upcasting).
I could keep a private List<T> myself, and make my public signature the
same as that of a List<T>, writing code to delegate every operation to
my private List<T>, with the addition of the event raising:
public class NotifyingList<T>
{
public delegate void ItemAddedHandler(T item);
public event ItemAddedHandler ItemAdded;
private List<T> items;
public void Add(T item)
{
items.Add(item);
ItemAdded(item);
}
public ReadOnlyCollection<T> AsReadOnly()
{
return items.AsReadOnly();
}
public int BinarySearch(T item)
{
return items.BinarySearch(item);
}
public void foo()
{
items.foo();
}
// etc
// etc
// for all 50 members
}
But this involves writing a huge amount of 'empty' code, simply to
achieve one very small end.
Thoughts?