You can achieve that by creating non-generic base classes for the generic base classes. Answer updated to avoid type castingcasting; to do so, ChildObjects property had to be IEnumerable<T> because it's type parameter is covariant, while classes, IList<T>, and ICollection<T> are contravariant.
You can achieve that by creating non-generic base classes for the generic base classes. Answer updated to avoid type casting.
You can achieve that by creating non-generic base classes for the generic base classes. Answer updated to avoid type casting; to do so, ChildObjects property had to be IEnumerable<T> because it's type parameter is covariant, while classes, IList<T>, and ICollection<T> are contravariant.
You can achieve that by creating non-generic base classes for the generic base classes. Answer updated to avoid type casting.
public abstract class ManagerBase { publicprotected List<ChildBase>ManagerBase() ChildObjects { get; set; } innerChildObjectList = new List<ChildBase>(); } private IList innerChildObjectList; public abstractIEnumerable<ChildBase> classChildObjects Manager<T> { : ManagerBase get { foreach (ChildBase child in innerChildObjectList.OfType<ChildBase>()) yield return child; } } public void AddChild<T>(T child) where T : ChildBase { public Manager innerChildObjectList.Add(child); {} public void RemoveChild<T>(T child) ChildObjectswhere =T new: List<T>ChildBase { innerChildObjectList.Remove(child); } public newbool List<T>ContainsChild<T>(T ChildObjects child) where T : {ChildBase { get { return base.ChildObjects.Cast<T>()innerChildObjectList.ToListContains(child); } //Add 'Insert', 'RemoveAt' methods setif needed. } public abstract class Manager<T> : ManagerBase where T : ChildBase { base. public new IEnumerable<T> ChildObjects = value { get { return base.ToList<ChildBase>ChildObjects.OfType<T>(); } } } public abstract class ChildBase { publicprotected ChildBase(ManagerBase ParentMgrmgr) { get; set; } ParentMgr = mgr; } private ManagerBase parentMgr; public abstractManagerBase classParentMgr Child<T> { : ChildBase get { return parentMgr; } where T : ManagerBase set { public Child if (TparentMgr != null && parentMgr.ContainsChild(this)) { parentMgr.RemoveChild(this); ParentMgr parentMgr = parentMgr;value; ParentMgr.ChildObjects parentMgr.AddAddChild(this); } } } public abstract class Child<T> : ChildBase where T : ManagerBase { protected Child(T mgr) : base (mgr) { } public new T ParentMgr { get { return (T)base.ParentMgr;ParentMgr as T; } set { base.ParentMgr = value; } } } You can achieve that by creating non-generic base classes for the generic base classes.
public abstract class ManagerBase { public List<ChildBase> ChildObjects { get; set; } } public abstract class Manager<T> : ManagerBase where T : ChildBase { public Manager() { ChildObjects = new List<T>(); } public new List<T> ChildObjects { get { return base.ChildObjects.Cast<T>().ToList(); } set { base.ChildObjects = value.ToList<ChildBase>(); } } } public abstract class ChildBase { public ManagerBase ParentMgr { get; set; } } public abstract class Child<T> : ChildBase where T : ManagerBase { public Child(T parentMgr) { ParentMgr = parentMgr; ParentMgr.ChildObjects.Add(this); } public new T ParentMgr { get { return (T)base.ParentMgr; } set { base.ParentMgr = value; } } } You can achieve that by creating non-generic base classes for the generic base classes. Answer updated to avoid type casting.
public abstract class ManagerBase { protected ManagerBase() { innerChildObjectList = new List<ChildBase>(); } private IList innerChildObjectList; public IEnumerable<ChildBase> ChildObjects { get { foreach (ChildBase child in innerChildObjectList.OfType<ChildBase>()) yield return child; } } public void AddChild<T>(T child) where T : ChildBase { innerChildObjectList.Add(child); } public void RemoveChild<T>(T child) where T : ChildBase { innerChildObjectList.Remove(child); } public bool ContainsChild<T>(T child) where T : ChildBase { return innerChildObjectList.Contains(child); } //Add 'Insert', 'RemoveAt' methods if needed. } public abstract class Manager<T> : ManagerBase where T : ChildBase { public new IEnumerable<T> ChildObjects { get { return base.ChildObjects.OfType<T>(); } } } public abstract class ChildBase { protected ChildBase(ManagerBase mgr) { ParentMgr = mgr; } private ManagerBase parentMgr; public ManagerBase ParentMgr { get { return parentMgr; } set { if (parentMgr != null && parentMgr.ContainsChild(this)) parentMgr.RemoveChild(this); parentMgr = value; parentMgr.AddChild(this); } } } public abstract class Child<T> : ChildBase where T : ManagerBase { protected Child(T mgr) : base (mgr) { } public new T ParentMgr { get { return base.ParentMgr as T; } set { base.ParentMgr = value; } } } You can achieve that by creating non-generic base classes for the generic base classes.
public abstract class ManagerBase { public List<ChildBase> ChildObjects { get; set; } } public abstract class Manager<T> : ManagerBase where T : ChildBase { public Manager() { ChildObjects = new List<T>(); } public new List<T> ChildObjects { get { return base.ChildObjects.Cast<T>().ToList(); } set { base.ChildObjects = value.ToList<ChildBase>(); } } } public abstract class ChildBase { public ManagerBase ParentMgr { get; set; } } public abstract class Child<T> : ChildBase where T : ManagerBase { public Child(T parentMgr) { ParentMgr = parentMgr; ParentMgr.ChildObjects.Add(this); } public new T ParentMgr { get { return (T)base.ParentMgr; } set { base.ParentMgr = value; } } } Now this will be okay:
public class CatalogManager : Manager<Catalog> { } public class Catalog : Child<CatalogManager> { public Catalog(CatalogManager parentMgr) : base(parentMgr) { } }