Наследование от обобщенного класса с IEnumerator

74
28 марта 2022, 14:40

Вопрос больше теоретический. Но буду признателен и за практическое решение, а дальше, на его основе, смогу додумать.

До сего момента плотно с обобщениями работать не приходилось и уперся в то, что второй день не могу внятно сформулировать Гуглу вопрос и, соответственно, получаю ответы как вот сейчас на вопрос "как вставить текст между <> в редакторе стековерфлоу" - ответы про вставку их как угодно и куда угодно, кроме редактора на сайте :)

Возникла задача

  1. Реализовать некий базовый класс. При этом поля ID и Value - обобщенные, ID ограничено - IConvertible, IComparable

  2. Реализовать коллекцию (наподобие List) для этих элементов, в которой реализованы все необходимые методы работы с элементами

  3. Реализовать коллекцию (наподобие Dictionary) для работы с коллекциями из п. 2, а через них и доступ к элементам из п. 1
    (т.е. получается, что пп 2-3 обеспечивают еще и доступ по типу row\column для элемента, но, тем не менее, юзать DataTable или другие встроенные типы - не подходит)

Смысл в том, что элементы содержат все необходимые свойства\методы для разных, но однотипных задача (в основном справочники всякие). И, по задумке - ID может быть цифрой, к которой привязывается Value - строка, или наоборот или ID - строка\цифра\дата - Value класс.

Как следствие - TID, TVаlue элементов указывается так же и для коллекций всех уровней (п.п. 2-3) и, стало быть, если для п.3 создаем MyDic<string, string> то и все остальное, вплоть до элементов, будет этого типа.

В пп. 2-3 реализован интерфейс IEnumerable.

В итоге получается следующее

  1. Наследую базовый класс StrElm : BaseElm<string, string>
  2. Для работы с ним наследую StrLst : BaseLst<string, string>

Уже получается чепуха. Т.к. IEnumerable, реализованный в BaseLst, возвращает BaseElm<TID, TValue>, а не StrElm.

При этом компилятор итерацию foreach(StrElm el in StrLst) пропускает, в реалтайме Exception приведения типов.

А если var - то возвращает, соотв. BaseElm<string, string>, а не StrElm

Вот, собственно, и вопрос. Как бы это обойти.
А, точнее - догадываюсь, что косяк у меня в "архитектуре" оттого, что опыта работы с обобщениями маловато, а сама задача, с виду, "типовая" - организовать работу с элементами с нужным функционалом и уже вчера была бы решена, если бы типы были заранее определенными.
Поэтому и вопрос более "глобальный" - как это реализуется в случае обобщенных типов и где бы об этом почитать ( или глянуть примеры), но, по возможности, под конкретную эту задачу (увы, перечитать Рихтера или, хотя бы, Троелсена, осмыслить обобщения и написать потому как надо уже не успеваю :) )

Answer 1

Честно говоря не совсем понял что вы хотите, лучше хотя бы псевдокодом показать что вы хотите получить если не знаете как это реализовать на целевом языке, но в комментарии код писать ни разу не здорово, поэтому пусть пока повисит в виде ответа.

По описанию вам вероятно нужно что-то такое

class BaseType<TId, TValue> where TId : struct, IConvertible, IComparable
{
    public TId Id { get; set; }
    public TValue Value { get; set; }
    //ваша дополнительная логика
}
class CustomList<TElem, TId, TValue> : List<TElem> 
    where TId : struct, IConvertible, IComparable
    where TElem : BaseType<TId, TValue> 
{ 
    //ваша дополнительная логика
}
class CustomDictionary<TKey, TDictVAlue, TElem,  TId, TValue> : Dictionary<TKey, TElem> 
    where TId : struct, IConvertible, IComparable
    where TElem : BaseType<TId, TValue> 
    where TDictVAlue : CustomList<TElem, TId, TValue>
{
    //ваша дополнительная логика
}

Но это такое себе решение и действительно попахивает проблемами в архитектуре. Если что-то непонятно - добавлю уточнения, если совсем не попал - совсем удалю.

READ ALSO
Многоуровневая архетектура(Class Library)

Многоуровневая архетектура(Class Library)

Пусть нужно сделать проект с многоуровневой архитектуройКак и в каких случаях нужно делать так: Class Libraries: Entites, DLayer, DTO,BLayer, Presenttion Layer, Core или...

91
DataGridView с датами

DataGridView с датами

Есть таблица

166