为何C#编译器选择Dapper的IDbConnection扩展方法而非自定义类实例方法?
问题原因解析
这是C#方法调用的解析规则导致的,核心逻辑如下:
- Dapper的
QueryAsync<T>是扩展方法,并非IDbConnection接口本身定义的成员。 - 你的
LoggingDbConnection虽然实现了IDbConnection,并且自行编写了带日志逻辑的QueryAsync<T>实例方法,但这个方法并没有被包含在IDbConnection的接口契约中。 - 当你通过
IDbConnection类型的变量(也就是你的_dbConnection字段)调用方法时,C#编译器只会优先查找该接口显式声明的方法。由于IDbConnection里根本没有QueryAsync<T>这个方法,编译器就会直接匹配Dapper的扩展方法,完全不会去调用LoggingDbConnection中额外添加的实例方法。
简单来说:接口类型的变量只能调用接口里定义的方法,你自定义的实例方法不在接口契约里,编译器识别不到,自然就走了扩展方法的逻辑。
可行的解决思路
- 把字段类型从
IDbConnection改成LoggingDbConnection,这样编译器会优先调用类的实例方法; - 自定义一个新的接口(比如
ILoggingDbConnection),把QueryAsync<T>加入接口契约,让LoggingDbConnection实现这个接口,然后依赖注入时用这个新接口; - 让
LoggingDbConnection在内部封装Dapper的调用,比如所有Dapper扩展方法的调用都经过你的日志逻辑处理后,再转发给底层的数据库连接。
内容的提问来源于stack exchange,提问作者Shad
相关产品推荐
相关产品推荐

