Comment implémenter le générique IEnumerable ou IDictionary pour éviter le CA1006?

c# dapper fxcop generics ienumerable

Question

Par curiosité, j'aimerais savoir comment implémenter au mieux une classe qui pourrait être utilisée pour éviter l'avertissement CA1006

CA1006: Microsoft.Design: envisagez une conception dans laquelle 'IReader.Query (String, String)' n'implique pas le type générique 'IList (Of IDictionary (Of String, Object))'.

C'est la méthode qui retourne le type générique

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();
    }
}

Quelque chose comme

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

MODIFIER:

Suite aux suggestions de Marc, j'ai encapsulé le générique imbriqué dans cette classe

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

Réponse acceptée

Tout d'abord, notez qu'il s'agit d'une directive de conception, et non d'une erreur de compilation. Une approche valable ici serait: l'ignorer.

Un autre pourrait être - encapsulez-le; c.-à-d. renvoyer une List<QueryRow> , où QueryRow est un wrapper superficiel sur un IDictionary<string,object> avec un indexeur, c.-à-d.

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; }
    }
}

Ensuite, étant donné que vous y accédez via dapper, remplissez via:

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

Une autre option (que je n’apprécie pas énormément) pourrait être: retourner DataTable .

s'en va se laver les mains après avoir tapé DataTable ... gah! deux fois maintenant




Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi