How can I detect adds to a generic list in C# 4.0?
I have a subclass of List<Location>
called LocationList
. This is a convenient way for us to add other properties (like IsExpanded
and such that we can use in the UI. Good enough. But now, we want each location to be aware of its parent. As such, we need to be notified when something is added to LocationList, but you can't override Add
and Remove
. While we can use ObservableCollection, that's more of a View/ViewModel construct. This is pure model data.
Sure we could manually set the parent when adding it to the collection, but I hate non-automated logic like that as there's nothing to enforce its set correctly. Letting the collection (well, List) automatically say 'Hey... you're being added, so I'll set your parent to the开发者_高级运维 class that owns me." is what I'm after.
My thought is to instead of subclass List<Location>
to instead just create a straight class that uses a List<Location>
internally, and then I can simply expose my own Add/Remove methods and handle the adjustments to 'Parent' in there. However, doing so breaks being able to enumerate over the internal collection since it's inside.
That said, is there any way to either listen to changes to List<Location>
, or at least delegate its IEnumerable
interface from the wrapped object to its wrapper?
Change your LocationList to inherit from Collection<Location>
instead. I don't know why List<T>
isn't sealed, but it's not extendable.
Source: Framework Design Guidelines, Second Edition, Page 251:
List<T>
is optimized for performance and power at the cost of cleanness of the APIs and flexibility.
List<T>
has protected members InsertItem<T>
, RemoveItem<T>
etc that you can override in your derived class to do what you want.
** UPDATE **
Actually the above is incorrect, it's Collection<T>
that has these protected methods. In general, when deriving custom List classes, it is recommended to derive from Collection<T>
rather than List<T>
.
See this answer.
My thought is to instead of subclass List to instead just create a straight class that uses a List internally, and then I can simply expose my own Add/Remove methods and handle the adjustments to 'Parent' in there. However, doing so breaks being able to enumerate over the internal collection since it's inside.
You can still implement IEnumerable<Location>
on your custom collection. Use the List<>
as the internal implementation detail of the class, and you can allow enumeration via the interface.
class LocationList : IEnumerable<Location>
{
List<Location> _list; // initialize somewhere
public IEnumerator<Location> GetEnumerator()
{
return _list.GetEnumerator();
}
IEnumerable.IEnumerator GetEnumerator()
{
return this.GetEnumerator();
}
// ... your other custom properties and methods
}
Try the generic BindingList<T>
, which raises events when items are added and removed.
However, doing so breaks being able to enumerate over the internal collection since it's inside.
This is not true assuming you follow proper technique and implement IEnumerable
and ICollection
But I would use Observable collection instead of reinventing the wheel.
And of course you can use Reactive extensions to do what you need.
You can either using Observer pattern
精彩评论