Dabagab
Dabagab

Reputation: 2835

How can I add child object to the parent generic type in c#

In java I can do it with extends keyword in Generic Type but in C# I cannot figure out.

I have a 3 classes, one of them is the base class.

public class BaseEntity { 
    public string Id {get;set;} 
}

public class EntityA : BaseEntity {}

public class EntityB: BaseEntity {}

Then I have a mock class for dataset. With generic type, the minimum constraint is the BaseEntity

public class MockDataStore<T> : IDataStore<T> where T : BaseEntity
{
    List<T> items = new List<T>();

    public async Task<bool> AddAsync(T item)
    {           
    }

    public async Task<bool> UpdateAsync(T item)
    {           
    }

    public async Task<bool> DeleteAsync(T item)
    {           
    }
}

But when I want to add one of the child class to the items list, the compailer says this is not possible.

Cannot convert From EntityA to T

items.Add(new EntityA());

I want to use the generic type, because of Add, Update and Delete methods.

Yes if I use the List<BaseEntity> = new List<BaseEntity>() then I will not get the cannot convert message. But in this case the Add, Update and Delete methods will be wrong.

However I have added where T : BaseEntity this constraints and grr.

What I want to achive is that the T : BaseEntity typed items list filled up with the child items of the BaseEntity.

How can I do it?

Upvotes: 3

Views: 1526

Answers (1)

Camilo Terevinto
Camilo Terevinto

Reputation: 32068

I think you have two options here:

1. Remove the unneeded generics.

I don't think you need generics here at the class level. You can just have a list of the base class and work with that:

public class MockDataStore
{
    List<BaseEntity> items = new List<BaseEntity>();

    public async Task<bool> AddAsync(BaseEntity item)
    {           
    }

    public async Task<bool> UpdateAsync(BaseEntity item)
    {           
    }

    public async Task<bool> DeleteAsync(BaseEntity item)
    {           
    }
}

2. Use generics through a proper inheritance chain.

This is probably not what you want, as you would end up with multiple classes, but I will leave it here just in case:

public abstract class MockDataStoreBase<T> : IDataStore<T> where T : BaseEntity
{
    protected List<T> items = new List<T>();

    public virtual async Task<bool> AddAsync(T item)
    {           
    }

    public async Task<bool> UpdateAsync(T item)
    {           
    }

    public async Task<bool> DeleteAsync(T item)
    {           
    }
}

public class EntityADataStore : MockDataStoreBase<EntityA>
{
    public override async Task<bool> AddAsync(EntityA item)
    {
        bool result = await base.AddAsync(item);
    }

    //...
}

Now, EntityADataStore.items will be a List<EntityA>.

Upvotes: 4

Related Questions