M
Mike D Sutton
I'm frequently using generic lists to represent child lists in my current system, and often require a bi-directional
link between them (so a child knows it's parent as well as the parent having the list of children.)
Currently I'm providing a "new" implementation of Add() and Remove(), which set and null the parent link on the child
object respectively, which is ok but a bit tedious for every parent-child relationship in the system. In addition to
this, the other functions which manipulate the list items (Insert, InsertRange, RemoveAt, RemoveAll etc) will allow list
access without managing the child's parent property.
What I'm really after is a generic list type that would expose either some events, or virtual methods that can be
overridden to add additional functionality when adding or removing elements. Probably along the lines of:
***
interface IHaveAParent<T> { T Parent { get; set; } }
abstract class CParentList<T> : List<T> where T : IHaveAParent<CParentList<T>> {
// Manage parent properties
public virtual void OnAddOne(T item) { item.Parent = this; }
public virtual void OnAddList(IEnumerable<T> list) {
foreach (T item in list) item.Parent = this; }
public virtual void OnRemoveOne(T item) { item.Parent = null; }
public virtual void OnRemoveList(IEnumerable<T> list) {
foreach (T item in list) item.Parent = null; }
public new void Add(T item) {
OnAddOne(item);
base.Add(item);
}
public new void Remove(T item) {
OnRemoveOne(item);
base.Remove(item);
}
// Other "new" methods here...
}
class CExampleChildItem : IHaveAParent<CParentList<CExampleChildItem>> {
#region IHaveAParent<CParentList<CExampleChildItem>> Members
private CParentList<CExampleChildItem> m_Parent;
public CParentList<CExampleChildItem> Parent {
get { return m_Parent; }
set { m_Parent = value; }
}
#endregion
}
class ExampleList : CParentList<CExampleChildItem> { /* Stuff */ }
***
I just really wanted to check that I'm not missing some GenericListWithChangeNotifications<> class somewhere which
already offers this functionality before I go and write my own, or is there some other way of achieving the desired
functionality?
Cheers,
Mike
link between them (so a child knows it's parent as well as the parent having the list of children.)
Currently I'm providing a "new" implementation of Add() and Remove(), which set and null the parent link on the child
object respectively, which is ok but a bit tedious for every parent-child relationship in the system. In addition to
this, the other functions which manipulate the list items (Insert, InsertRange, RemoveAt, RemoveAll etc) will allow list
access without managing the child's parent property.
What I'm really after is a generic list type that would expose either some events, or virtual methods that can be
overridden to add additional functionality when adding or removing elements. Probably along the lines of:
***
interface IHaveAParent<T> { T Parent { get; set; } }
abstract class CParentList<T> : List<T> where T : IHaveAParent<CParentList<T>> {
// Manage parent properties
public virtual void OnAddOne(T item) { item.Parent = this; }
public virtual void OnAddList(IEnumerable<T> list) {
foreach (T item in list) item.Parent = this; }
public virtual void OnRemoveOne(T item) { item.Parent = null; }
public virtual void OnRemoveList(IEnumerable<T> list) {
foreach (T item in list) item.Parent = null; }
public new void Add(T item) {
OnAddOne(item);
base.Add(item);
}
public new void Remove(T item) {
OnRemoveOne(item);
base.Remove(item);
}
// Other "new" methods here...
}
class CExampleChildItem : IHaveAParent<CParentList<CExampleChildItem>> {
#region IHaveAParent<CParentList<CExampleChildItem>> Members
private CParentList<CExampleChildItem> m_Parent;
public CParentList<CExampleChildItem> Parent {
get { return m_Parent; }
set { m_Parent = value; }
}
#endregion
}
class ExampleList : CParentList<CExampleChildItem> { /* Stuff */ }
***
I just really wanted to check that I'm not missing some GenericListWithChangeNotifications<> class somewhere which
already offers this functionality before I go and write my own, or is there some other way of achieving the desired
functionality?
Cheers,
Mike