C#调用重载方法报错要求引用未使用的IMetadata类型如何解决
这个报错是C#编译器重载决议逻辑导致的:编译器扫描所有可见的CreateConnection重载做匹配优先级判断时,需要解析所有参数的类型定义,即使你实际调用的不是IMetadata参数的重载,只要该重载对调用项目可见,就会触发IMetadata的类型检查。三元运算符的返回类型推断逻辑会进一步扩大编译器的重载扫描范围,所以比普通的单分支调用更容易触发该问题。
方案1:将三元运算符替换为
if-else分支
两个分支的调用会被编译器独立做重载决议,不会关联扫描所有重载,不需要解析IMetadata类型即可完成匹配。修改后代码如下:IConnection connection; if (ticket != null) { connection = manager.CreateConnection(ticket); } else { connection = manager.CreateConnection(sso, user, password); }该方案无需修改底层服务代码,仅调整调用端写法即可,改造成本最低。
方案2:调整
IMetadata参数重载的可见性
将CreateConnection(IMetadata metadata)重载的访问修饰符改为internal,再通过[InternalsVisibleTo]特性将需要调用该重载的项目设为友元程序集。调用项目无法看到该重载,编译器自然不会触发IMetadata的类型检查。
该方案不需要修改任何调用端代码,适合可以调整底层服务定义的场景。方案3:显式指定参数类型强制匹配重载
给ticket参数加上显式的string类型转换,直接告诉编译器需要匹配的是string参数的重载,不需要扫描其他重载选项:IConnection connection = ticket != null ? manager.CreateConnection((string)ticket) : manager.CreateConnection(sso, user, password);该方案可以保留三元运算符的写法,改造成本极低。
方案4:通过条件编译移除调用端可见的
IMetadata重载
给包含CreateConnection重载的类加上partial修饰,将IMetadata参数的重载拆分到单独的代码文件中,在服务项目编译时包含该文件,在对外发布的引用包/编译分支中排除该文件,调用项目可见的重载列表里不会存在IMetadata参数的版本,自然不会触发报错。
该方案适合对外提供公共SDK的场景,不需要调整调用端代码。
内容的提问来源于stack exchange,提问作者tree7514

