Quelles sont les causes "les méthodes d'extension ne peuvent pas être envoyées dynamiquement" ici?

.net c# compiler-errors dapper extension-methods

Question

Erreur de compilation

'System.Data.SqlClient.SqlConnection' n'a pas de méthode applicable nommée 'Query' mais semble avoir une méthode d'extension de ce nom. Les méthodes d'extension ne peuvent pas être distribuées dynamiquement. Envisagez de convertir les arguments dynamiques ou d'appeler la méthode d'extension sans la syntaxe de la méthode d'extension.

Maintenant, je sais comment contourner le problème, mais j'essaie de mieux comprendre l'erreur elle-même. J'ai un cours que je construis pour tirer parti de Dapper. Au final, je vais fournir des fonctionnalités plus personnalisées pour simplifier notre accès aux données. En particulier construire en traçant et autres choses. Cependant, pour le moment, c'est aussi simple que cela:

public class Connection : IDisposable
{
    private SqlConnection _connection;

    public Connection()
    {
        var connectionString = Convert.ToString(ConfigurationManager.ConnectionStrings["ConnectionString"]);
        _connection = new SqlConnection(connectionString);
        _connection.Open();
    }

    public void Dispose()
    {
        _connection.Close();
        _connection.Dispose();
    }

    public IEnumerable<dynamic> Query(string sql, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null)
    {
        // this one works fine, without compile error, so I understand how to
        // workaround the error
        return Dapper.SqlMapper.Query(_connection, sql, param, transaction, buffered, commandTimeout, commandType);
    }

    public IEnumerable<T> Query<T>(string sql, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null)
    {
        // this one is failing with the error
        return (IEnumerable<T>)_connection.Query(sql, param, transaction, buffered, commandTimeout, commandType);
    }
}

mais, chose intéressante, si je devais simplement émettre une déclaration comme celle-ci:

_connection.Query("SELECT * FROM SomeTable");

il compile très bien.

Donc, quelqu'un peut-il m'aider s'il vous plaît comprendre pourquoi tirer parti de la même surcharge dans ces autres méthodes échoue avec cette erreur?

Réponse acceptée

Donc, quelqu'un peut-il m'aider s'il vous plaît comprendre pourquoi tirer parti de la même surcharge dans ces autres méthodes échoue avec cette erreur?

Précisément parce que vous utilisez une valeur dynamique ( param ) comme un des arguments. Cela signifie qu'il utilisera la distribution dynamique ... mais la distribution dynamique n'est pas prise en charge pour les méthodes d'extension.

La solution est simple cependant: appelez directement la méthode statique:

return SqlMapper.Query(_connection, sql, param, transaction,
                       buffered, commandTimeout, commandType);

(En supposant que vous ayez vraiment besoin de param pour être de type dynamic , bien sûr ... comme indiqué dans les commentaires, il se peut très bien que vous souhaitiez simplement le changer en object .)


Réponse populaire

Une autre solution au même problème consiste à appliquer une conversion de type à la valeur dynamique.

J'ai rencontré la même erreur de compilation avec:

Url.Asset( "path/" + article.logo );

Ce qui a été résolu en faisant:

Url.Asset( "path/" + (string) article.logo );

Remarque: la valeur dynamique est connue pour être une chaîne, dans ce cas; un fait renforcé par la concaténation de chaînes présente.




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