Как реализовать универсальный IEnumerable или IDictionary, чтобы избежать CA1006?

Из любопытства я хотел бы знать, как наилучшим образом реализовать класс, который можно использовать, чтобы избежать предупреждения CA1006

CA1006: Microsoft.Design: рассмотрим схему, в которой IReader.Query(String, String) не вкладывает универсальный тип "IList(Of IDictionary(Of String, Object))".

Это метод, который возвращает универсальный тип

public virtual IList<IDictionary<string, object>> Query(
    string fullFileName, 
    string sheetName)
{
    using (var connection = new OdbcConnection(
        this.GetOdbcConnectionString(fullFileName)))
    {
        connection.Open();
        return connection
            .Query(string.Format(
                CultureInfo.InvariantCulture,
                SystemResources.ExcelReader_Query_select_top_128___from__0_,
                sheetName))
            .Cast<IDictionary<string, object>>()
            .ToList();
    }
}

Что-то вроде

SourceData<T, U> Query(string fullFileName, string sheetName)
SourceData Query(string fullFileName, string sheetName)

РЕДАКТИРОВАТЬ:

Следуя советам Марка, я инкапсулировал вложенный шаблон в этом классе.

public class QueryRow : List<KeyValuePair<string, object>>
{
    protected internal QueryRow(IEnumerable<KeyValuePair<string, object>> dictionary)
    {
        this.AddRange(dictionary.Select(kvp => kvp));
    }
}

1 ответ

Решение

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

Другое может быть - заключить это в капсулу; т.е. вернуть List<QueryRow>, где QueryRow это мелкая обертка над IDictionary<string,object> с индексатором, т.е.

public class QueryRow {
    private readonly IDictionary<string,object> values;
    internal QueryRow(IDictionary<string,object> values) {
        this.values = values;
    }
    public object this[string key] {
        get { return values[key]; }
        set { values[key] = value; }
    }
}

затем, поскольку к нему обращаются через dapper, заполните через:

var data = connection.Query(....)
        .Select(x => new QueryRow((IDictionary<string,object>)x).ToList()

Другой вариант (который мне не очень нравится) может быть: return DataTable,

уходит мыть руки после набора текста DataTable ... га! теперь дважды

Другие вопросы по тегам