Сравните тип IEnumerable <T> - PullRequest
       44

Сравните тип IEnumerable <T>

1 голос
/ 14 сентября 2010

У меня есть словарь, который возвращает мне метод в соответствии с переданным значением. Определяется следующим образом:

Dictionary<Type, IXmlWriterConverter>

Теперь я добавил новую функцию, для которой Key / type установлен в IEnumerable,Все идет нормально.Но когда я выполняю свой модульный тест со списком, содержащим две таблицы данных, но словарь не может найти ключ, например, преобразование моего типа отличается.

Почему это так?И какова будет правильная попытка решить мою проблему?

Редактировать: Извините, здесь запрошенный код; -)

Функция, которая генерирует значения теста:

public IEnumerable<DataTable> CreateTestDataTableList()
{
    var resultDataTable = new List<DataTable>();

    resultDataTable.Add(CreateTestTable("testTable1", 2));
    resultDataTable.Add(CreateTestTable("testTable2", 3));

    return resultDataTable;
}

Функция, вызываемая модульным тестом:

public void Write(XmlWriter xmlWriter, object value)
{
    ...
    converter = FindConverter(value.GetType());
}

Функция проверки словаря:

public IXmlWriterConverter FindConverter(Type type)
{
    if(Converters.ContainsKey(type))
    {
        return Converters[type];
    }
    return null;
}

2.Edit:

Код, который добавляет значения в словарь:

public void Add(IXmlWriterConverter xmlWriterConverter)
{
    if(Converters.ContainsKey(xmlWriterConverter.InputType))
    {
        Remove(xmlWriterConverter);
    }

    Converters.Add(xmlWriterConverter.InputType, xmlWriterConverter);
}

InputType является свойством только для чтения (get) конвертера.Я проверил тип, добавленный в словарь, и он был зарегистрирован как IEnumerable, однако, когда я проверял typeof при передаче моего списка, тип был List, а не IEnumerable.Мне сказали, что это происходит, потому что я передаю значения как объект.

Ответы [ 5 ]

4 голосов
/ 14 сентября 2010

Для меня это действительно вонючее решение, и оно снижает эффективность, но вы также можете перебрать метод GetInterfaces () для Type, как здесь:

List<DataTable> l = new List<DataTable>();
var t = l.GetType();
var ints = t.GetInterfaces();

Тогда вы можете выполнить поиск по типу и, если это не сработает, выполнить поиск по его интерфейсам.

Однако , это похоже на ужасный взлом, который обычно указывает на то, что нужно выполнить еще несколько проектных работ. Разве нельзя поместить тип списка в словарь? Нет ли лучшего способа сделать этот поиск?

Кроме того, примечание о поиске в словаре: более эффективно использовать метод TryGetValue, например:

public IXmlWriterConverter FindConverter(Type type)
{
    IXmlWriterConverter converter;
    if( Converters.TryGetValue(type, out converter) )
    {
        return converter;
    }

    return null;
}

Когда вы делаете это таким образом, он выполняет только один поиск в словаре, тогда как если вы используете ContainsKey, он должен выполнить два поиска.

1 голос
/ 24 сентября 2010

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

public void Write<TValue>(XmlWriter writer, TValue value) {
// ...
}

Это позволяет определить правильный тип для IEnumerableи оставляет другой метод Write, чтобы не нарушать существующий код.

0 голосов
/ 17 сентября 2010

InputType только для чтения (получить) свойство конвертера. Я проверил тип добавлен в словарь и который был зарегистрирован как IEnumerable, Однако, когда я проверил на typeof при прохождении в моем списке тип был Список и не IEnumerable. мне сказали что это происходит, потому что я прохожу в значения как объект.

Как говорят на MythBusters , ну, в этом ваша проблема! Хотя List является IEnumerable Type объектами, которые представляют каждый, определенно не так же. В жаргоне программиста, typeof(List) != typeof(IEnumerable). Вот почему поиск не работает.

0 голосов
/ 14 сентября 2010

Вы также должны опубликовать код своего местоположения , получив тестовых значений.Но исходя из того, что вы дали, возможно, вы используете неуниверсальный IEnumerable для получения значений вместо универсальной версии, которую вы используете для их генерации?

0 голосов
/ 14 сентября 2010

Возможно, вы пытаетесь получить тип списка, а не IEnumerable (в этом контексте наследование не будет работать)

Пожалуйста, вставьте код, который выполняет поиск, если вы хотите получить больше деталей и более точный ответ :)

...