Как реализовать универсальный IEnumerable или IDictionary, чтобы избежать CA1006? - PullRequest
9 голосов
/ 15 ноября 2011

Из любопытства я хотел бы знать, как наилучшим образом реализовать класс, который можно было бы использовать, чтобы избежать предупреждения 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 Ответ

12 голосов
/ 15 ноября 2011

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

Другой может быть - инкапсулировать его;т.е. вернуть 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 ...Г!теперь дважды

...