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

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

问题描述

编译错误

  

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

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

 公共类连接:IDisposable的
{
    私人的SqlConnection _connection;

    公共连接()
    {
        VAR的connectionString = Convert.ToString(ConfigurationManager.ConnectionStrings [的ConnectionString]);
        _connection =新的SqlConnection(的connectionString);
        _connection.Open();
    }

    公共无效的Dispose()
    {
        _connection.Close();
        _connection.Dispose();
    }

    公开的IEnumerable<动态>查询(SQL字符串,动态参数= NULL,IDbTransaction交易= NULL,布尔缓冲= TRUE,INT?的CommandTimeout = NULL,的CommandType?命令类型= NULL)
    {
        //这个工作得很好,没有编译错误,所以我知道如何
        //解决该错误
        返回Dapper.SqlMapper.Query(_connection,SQL,参数,事务,缓冲的CommandTimeout,命令类型);
    }

    公开的IEnumerable< T>查询< T>(?字符串SQL,动态参数= NULL,IDbTransaction交易= NULL,布尔缓冲= TRUE,INT的CommandTimeout = NULL,的CommandType命令类型= NULL)
    {
        //这一次失败,出现错误
        返程(IEnumerable的< T>)_ connection.Query(SQL,参数,事务,缓冲的CommandTimeout,命令类型);
    }
}
 

但有趣的是,如果我要简单地发出这样的语句:

  _connection.Query(SELECT * FROM SomeTable);
 

它编译就​​好了。

那么,能不能有人请帮助我理解为什么利用相同的过载与其他方法内部失败与错误?

解决方案
  

那么,能不能有人请帮助我理解为什么利用相同的过载与其他方法内部失败与错误?

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

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

 返回SqlMapper.Query(_connection,SQL,参数,交易,
                       缓冲的CommandTimeout,命令类型);
 

(这是假设你真的需要参数是类型当然,动态,...如指出的评论,你可能被罚款,只是将其更改为对象

Compile Error

'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.

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

it compiles just fine.

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?

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

(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.)

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

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