Need help on nested generic collections and item

Periasamy

New member
Joined
Mar 18, 2025
Messages
1
Programming Experience
10+
I have aa requirement of Collection classes inherited at multiple levels with corresponding Item class at each level as in below example.

C#:
    public interface IOwnable<TOwner>
    {
        TOwner Owner { get; set; }
    }

    public abstract class BaseItem
    {
        // Common properties and methods for all items
    }

    public abstract class OwnableCollection<TItem, TCollection> : List<TItem>
        where TItem : BaseItem, IOwnable<TCollection>
        where TCollection : OwnableCollection<TItem, TCollection>
    {
        protected OwnableCollection()
        {
        }

        public new void Add(TItem item)
        {
            item.Owner = (TCollection)this;
            base.Add(item);
        }

        public new void AddRange(IEnumerable<TItem> items)
        {
            foreach (var item in items)
            {
                Add(item);
            }
        }
    }

    // -------------------------------------------------

    public abstract class IntermediateCollection<TItem, TCollection> : OwnableCollection<TItem, TCollection>
        where TItem : IntermediateItem<TCollection>, IOwnable<TCollection>
        where TCollection : IntermediateCollection<TItem, TCollection>
    {
        // Additional shared implementation for intermediate collections
    }

    public abstract class IntermediateItem<TOwner> : BaseItem, IOwnable<TOwner>
        where TOwner : IntermediateCollection<IntermediateItem<TOwner>, TOwner>
    {
        public TOwner Owner { get; set; }
        // Additional shared implementation for intermediate items
    }

    // -------------------------------------------------

    public class SpecificCollection : IntermediateCollection<SpecificItem, SpecificCollection>
    {
        // Specific implementation for this collection
    }

    public class SpecificItem : IntermediateItem<SpecificCollection>
    {
        // Specific implementation for this item
    }

    // -------------------------------------------------

    public abstract class MoreSpecificCollection<TItem, TCollection> : IntermediateCollection<TItem, TCollection>
        where TItem : MoreSpecificItem<TCollection>, IOwnable<TCollection>
        where TCollection : MoreSpecificCollection<TItem, TCollection>
    {
        // Additional shared implementation for more specific collections
    }

    public abstract class MoreSpecificItem<TOwner> : IntermediateItem<TOwner>
        where TOwner : IntermediateCollection<MoreSpecificItem<TOwner>, TOwner>
    {
        // Additional shared implementation for more specific items
    }

    // -------------------------------------------------

    public class VerySpecificCollection : MoreSpecificCollection<VerySpecificItem, VerySpecificCollection>
    {
        // Very specific implementation for this collection
    }

    public class VerySpecificItem : MoreSpecificItem<VerySpecificCollection>
    {
        // Very specific implementation for this item
    }

    // -------------------------------------------------

In the above, I am unsure about implicit reference conversion for TItem in IntermediateCollection<TItem, TCollection> into IntermediateItem<TCollection>.

Any help on this would be greatly appreciated.
 
It's not clear what you're actually asking. What exactly is it that you're not clear about? Are you asking why something happens? Are you asking how to do something specific? If your saying that you're not sure why you can treat a reference of type TItem as type IntermediateItem<TCollection> inside an object of type IntermediateCollection<TItem, TCollection> then your answer is right here:
C#:
    public abstract class IntermediateCollection<TItem, TCollection> : OwnableCollection<TItem, TCollection>
        where TItem : IntermediateItem<TCollection>, IOwnable<TCollection>
        where TCollection : IntermediateCollection<TItem, TCollection>
That generic constraint literally says that every reference of type TItem will be to an object that is of type IntermediateItem<TCollection> or a type that inherits it. That is exactly why generic constraints exist: to enable you to assume certain types or functionality in generic code. If you tried to create an IntermediateCollection object where TItem was not type IntermediateItem<TCollection> then the compiler would flag it as an error.

If that's not what you were asking then I have no idea what you mean and you'll need to clarify.
 
Back
Top Bottom