Дисперсия с несколькими общими параметрами / ограничениями - PullRequest
0 голосов
/ 12 января 2019

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

public interface IItemContainer<TValue, TItem> where TItem : IItem<TValue>
{
    List<TItem> Items { get; set; }
}

public interface IItem<T>
{
    T Value { get; set; }
}

Я реализую это так:

public class ItemContainer1<TValue> : IItemContainer<TValue, Item1<TValue>>
{
    public List<Item1<TValue>> Items { get; set; }
}

public class Item1<T> : IItem<T>
{
    public T Value { get; set; }
}

Пока все работает, но я получаю сообщение об ошибке "Не удается неявно преобразовать" при назначении ниже:

IItemContainer<string, IItem<string>> container = new ItemContainer1<string>();

И я получу InvalidCastException, если попробую разыграть так:

IItemContainer<string, IItem<string>> container =
    (IItemContainer<string, IItem<string>>)new ItemContainer1<string>();

Что-то подсказывает мне, что у меня неверный параметр или ограничение (или оба). Вероятно, это проблема дисперсии, которую мне еще предстоит полностью обернуть. Что мне нужно сделать, чтобы сделать эту работу?

Edit: я не большой поклонник параметра TItem, но это единственный известный мне способ получить свойство List<TItem> типа List<Item1<TValue>>, а не List<IItem<TValue>>.

1 Ответ

0 голосов
/ 14 января 2019

Поскольку вы хотите, чтобы список имел тип Item1<TValue>, вы не можете привести его к менее конкретному IItem<TValue>. Установщик свойства типа IItem<TValue> должен быть успешным для любого допустимого средства реализации интерфейса. Вам нужно либо разрешить этот список типа IItem<TValue>, который, как вы заявили, вам не нужен, либо изменить архитектуру другим способом.

Если вам нужно только прочитать значения списка как IItem<TValue>, в отличие от использования интерфейса для создания нового списка, вы можете изменить интерфейс для чтения и приведения значений.

...