DictionaryExtention, работает для отдельных элементов, но не для списка <Item>, почему и как? - PullRequest
0 голосов
/ 05 марта 2020

Я пытаюсь получить два разных возвращаемых значения из методов расширения словаря для удобства. Первый - это предмет RealType, другой - List<RealType>.

. Проблема / вопрос в следующем: Получение одного RealType предмета работает как обаяние, получение списка аварийно завершает работу и требует реализации IConvertable. Разве нет вызова для преобразования полного списка?

Редактировать: Я пытаюсь преобразовать из Базовый класс в Производный класс , А не наоборот. Кроме того, я на 100% знаю, что данные будут иметь тип Производный класс , и вызывающий абонент каждый раз передает правильный тип без какой-либо вероятности ошибки.

Почему это так? Можно ли этого избежать, без «грязных» хитростей? Существует около двух десятков RealType - классов, которые начинаются с MyAbstractModel и сохраняются в List<Dictionary<string, MyAbstractModel>. Написание кода для двух десятков конверсий кажется не очень хорошей идеей, когда маленький грязный (?) Трюк, кажется, тоже делает это.

Рассмотрим следующий (работающий) класс DictionaryExtention

public static class DictionaryExtenders
{
    public static T GetItem<T>(this Dictionary<string, MyAbstractModel> instance, string key)
    {
        return (T)Convert.ChangeType(instance[key], typeof(T));
    }
}

Вызывается так: RealType item = myDictionary.GetItem<RealType>("choosenIDString");

Редактировать: Каждый словарь может иметь и будет иметь только один тип. Там никогда не будет два разных типа хранятся в одном. Да, этот код позволил бы это и выдавал ошибки, но в этом случае сохранение не требуется и не является частью моего вопроса.

Теперь, напротив, следующие GetList<RealType> вызовы расширения для реализации IConvertable:

public static List<T> GetList<T>(this Dictionary<string, MyAbstractModel> instance)
{
    return (List<T>)Convert.ChangeType(instance.Values.ToList(), typeof(List<T>));
}

Мне кажется, что я что-то здесь упускаю, потому что следующий обходной путь также возвращает List<RealType>, но не вызывает IConvertable. Я просто набираю oop словарь и каждый раз звоню GetItem<T>().

public static List<T> GetList<T>(this Dictionary<string, MyAbstractModel> instance)
{
    var temp = new List<T>();
    foreach (RealType myType in instance.Values.ToList())
    {
        temp.Add(instance.GetItem<T>(myType.ID));
    }
    return temp;
}

Это не похоже на solid решение, но похоже на обходной путь. Что мне здесь не хватает? Списки затрудняют меня из-за неправильного синтаксиса на моей стороне, или есть причина, которую я должен понять?

Ответы [ 2 ]

0 голосов
/ 05 марта 2020

вы можете попробовать таким образом

public static List<T> GetList<T>(this Dictionary<string, yourModel> instance)
{
    return instance.Values.Select(d => (T)Convert.ChangeType(d, typeof(T))).ToList();
}
0 голосов
/ 05 марта 2020

Ваши GetList реализации недопустимы. Все значения в словаре являются экземплярами классов, полученных из MyAbstractModel, но вы не можете привести их друг к другу во всех случаях. Например, ModelA и ModelB оба получены из MyAbstractModel. Но вы не можете разыграть ModelA до ModelB. Вы можете написать что-то вроде этого:

public static List<T> GetList<T>(this Dictionary<string, MyAbstractModel> instance) where T: MyAbstractModel
{
    return instance.Values.OfType<T>().ToList();
}

В этом случае вы получите все значения определенного типа T.

...