【问题标题】:What causes "extension methods cannot be dynamically dispatched" here?是什么原因导致“扩展方法无法动态调度”?
【发布时间】:2013-03-01 17:31:34
【问题描述】:

编译错误

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

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

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

它编译得很好。

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

【问题讨论】:

  • @pst,很公平,从技术上讲,它不是抛出的。
  • 为什么需要动态参数,而不是对象参数?您没有对其进行任何操作或方法调用。你是吗?

标签: c# .net compiler-errors extension-methods dapper


【解决方案1】:

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

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

解决方案很简单:直接调用静态方法即可:

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

(假设您确实需要 paramdynamic 类型,当然...如 cmets 中所述,您可能只需将其更改为 object 就可以了。)

【讨论】:

  • 这就是正是我要找的,非常感谢乔恩!解决它没有问题,就像您在示例中所做的那样,就像我在第一种方法中所做的那样,我只是想知道 为什么 是否有意义。而且我想我会把它改成object,因为我不需要对它执行任何操作。
  • @MichaelPerrenoud 你可能已经找到了这个,但在这种情况下FooSqlMapper;所以SqlMapper.Query(...)
  • @MarcGravell:谢谢,已修复。
  • @MikePerrenoud Here's a more complete answer 到,为什么?
【解决方案2】:

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

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

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

通过以下方式解决:

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

注意:动态值是众所周知的字符串,在这种情况下;存在的字符串连接强化了一个事实。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-04-23
    • 1970-01-01
    • 1970-01-01
    • 2018-05-25
    • 1970-01-01
    • 2010-09-29
    • 2015-02-16
    相关资源
    最近更新 更多