Как я могу добавить дочерний объект в родительский универсальный тип в C # - PullRequest
0 голосов
/ 22 мая 2018

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

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

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

public class EntityA : BaseEntity {}

public class EntityB: BaseEntity {}

Тогда у меня есть фиктивный класс для набора данных.Для универсального типа минимальное ограничение - 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());

Я хочу использовать универсальный тип из-за методов Add, Update и Delete.

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

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

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

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

1 Ответ

0 голосов
/ 22 мая 2018

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

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

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

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>.

...