Как добавить дочерний объект к родительскому родовому типу в c #

Dabagab спросил: 28 апреля 2018 в 09:25 в: c#

В java я могу сделать это с помощью ключевого слова extends в Generic Type, но в C # я не могу понять.

У меня есть 3 класса, один из которых - базовый класс.

public class BaseEntity { 
    public string Id {get;set;} 
}public class EntityA : BaseEntity {}public class EntityB: BaseEntity {}

Затем у меня есть класс mock для набора данных. С общим типом минимальным ограничением является 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)
    {           
    }
}

Но когда я хочу добавить один из дочернего класса в items список, компилятор говорит, что это невозможно.

Невозможно преобразовать из EntityA в T

items.Add(new EntityA());

Я хочу использовать общий типа, из-за методов добавления, обновления и удаления.

Да, если я использую List<BaseEntity> = new List<BaseEntity>(), то я не получу сообщение не может преобразовать. Но в этом случае методы добавления, обновления и удаления будут неправильными.

Однако я добавил where T : BaseEntity эти ограничения и grr.

Что я хочу достичь что T : BaseEntity напечатал items список, заполненный дочерними элементами BaseEntity.

Как я могу это сделать?

1 ответ

Есть решение
Camilo Terevinto ответил: 28 апреля 2018 в 09:48

Я думаю, у вас есть два варианта:

1. Удалите ненужные дженерики.

Я не думаю, что вам нужны дженерики здесь на уровне класса. Вы можете просто иметь список базового класса и работать с ним:

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. Используйте generics через правильную цепочку наследования.

Это, вероятно, не то, что вы хотите, так как вы закончите с несколькими классами, но я оставлю его здесь на всякий случай:

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);
    }    //...
}

Теперь EntityADataStore.items будет List<EntityA>.