是什么原因导致“扩展方法不能被动态调度”在这里?是什么原因导致“扩展方法不能被动态调度”在这里?(W

2019-05-12 06:48发布

编译错误

“System.Data.SqlClient.SqlConnection”有一个名为“查询”不适用的方法,但似乎有这个名字的扩展方法。 扩展方法不能动态调度。 考虑强制转换动态参数或调用没有扩展方法的语法的扩展方法。

现在,我知道如何解决这个问题,但我想更好地了解错误本身。 我有我建立利用小巧精致的类。 最终我将提供一些更多的自定义功能,使我们的类型的数据访问很多更精简。 在跟踪和东西特别的建筑。 然而,现在它是如此简单:

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

但有趣的是,如果我只是发出如下声明:

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

它编译就好了。

那么,能不能有人请帮助我理解为什么利用里面的那些其他的方法是与该错误不成的过载?

Answer 1:

那么,能不能有人请帮助我理解为什么利用里面的那些其他的方法是与该错误不成的过载?

正因为您使用的是动态值( param )作为参数之一。 这意味着它将使用动态调度...但不支持扩展方法的动态调度。

解决方法很简单,但:只需要直接调用静态方法:

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

(这是假设你真的需要param为类型的dynamic ,当然......在评论中指出,你可能会被罚款,只是将其更改为object )。



Answer 2:

对同一个问题的另一个解决方案是将类型转换适用于动态值。

我遇到了同样的编译错误有:

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

这是由这样解决:

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

注意:动态值是公知的是字符串,在这种情况下; 通过字符串连接是存在增强的事实。



文章来源: What causes “extension methods cannot be dynamically dispatched” here?