什么原因导致“扩展方法不能被动态调度"?这里? [英] What causes "extension methods cannot be dynamically dispatched" here?

查看:21
本文介绍了什么原因导致“扩展方法不能被动态调度"?这里?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

'System.Data.SqlClient.SqlConnection' 没有名为 'Query' 的适用方法,但似乎具有该名称的扩展方法.不能动态调度扩展方法.考虑强制转换动态参数或在没有扩展方法语法的情况下调用扩展方法.

'System.Data.SqlClient.SqlConnection' has no applicable method named 'Query' but appears to have an extension method by that name. Extension methods cannot be dynamically dispatched. Consider casting the dynamic arguments or calling the extension method without the extension method syntax.

现在,我知道如何解决这个问题,但我正在努力更好地了解错误本身.我正在构建利用 Dapper 的课程.最后,我将提供一些更多的自定义功能,使我们的数据访问类型更加简化.特别是在追踪和东西方面的​​建设.但是,现在就这么简单:

Now, I know how to work around the problem, but I'm trying to get a better understanding of the error itself. I have class that I'm building to leverage Dapper. In the end I'm going to provide some more custom functionality to make our type of data access a lot more streamlined. In particular building in tracing and stuff. However, right now it's as simple as this:

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

但有趣的是,如果我只是发表这样的声明:

but interestingly enough, if I were to simply issue a statement like this:

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

它编译得很好.

那么,有人可以帮助我理解为什么在其他方法中利用相同的重载会因该错误而失败吗?

So, can somebody please help me understand why leveraging the same overload inside of those other methods is failing with that error?

推荐答案

那么,有人可以帮助我理解为什么在其他方法中利用相同的重载会因该错误而失败吗?

So, can somebody please help me understand why leveraging the same overload inside of those other methods is failing with that error?

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

Precisely because you're using a dynamic value (param) as one of the arguments. That means it will use dynamic dispatch... but dynamic dispatch isn't supported for extension methods.

不过解决方法很简单:直接调用静态方法:

The solution is simple though: just call the static method directly:

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

(假设您确实需要 paramdynamic 类型,当然……正如评论中所述,您可能只需将其更改为object.)

(That's assuming you really need param to be of type dynamic, of course... as noted in comments, you may well be fine to just change it to object.)

这篇关于什么原因导致“扩展方法不能被动态调度"?这里?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆