扩展方法调用不会编译,但对相同代码的静态方法调用会编译

2023-12-25

库 A 使用 C# 扩展方法调用库 B。

我从 C# 编译器中收到一个奇怪的错误:

类型“System.Windows.Forms.Control”是在程序集中定义的 没有被引用。您必须添加对程序集的引用 'System.Windows.Forms,版本=4.0.0.0

库 A 或 B 都不依赖于System.Windows.Forms.Control,A 也不依赖于System.Windows.Forms.Control. System.Windows.Forms.Control仅从同一解决方案中的另一个项目引用。

奇怪的是,如果我将调用语法更改为静态方法,它就会成功编译。

//static method syntax works fine
var leads = SourceLeadConfigurationHelper.GetLeads(enLeadSystem);

//extension method syntax cause error
//error The type 'System.Windows.Forms.Control' is defined in an assembly that is not referenced. 
var leads = enLeadSystem.GetLeads();

扩展方法如下所示:

public static class SourceLeadConfigurationHelper
{      
    public static IList<ChannelID> GetLeads(this LeadSystem leadSystem);
    public static IList<ChannelID> GetLeads(this SourceLeadConfiguration slc);
    public static IList<ChannelID> GetLeads(LeadSystem leadSystem, bool throwException);
}

所以你会发现检测使用哪个扩展没有问题。LeadSystem是一个枚举,SourceLeadConfiguration是一个类。

我有 Visual Studio 2013 更新 5、.NET Framework 4.0。


这是对 C# 编译器行为的一致抱怨,让程序员非常抓狂。不幸的是,没有规范的问答,每个案例都是不同的。第一份报告在 VS2012/.NET 4.5 时间范围内开始出现。编译器过去并没有这样做,它听起来像是一个错误修复,其影响比预期更大。我们也没有经常听到它,大多数程序员只是按照错误消息中的指导并添加程序集引用。你也应该如此,它可以轻松解决问题。

尝试在这里描述一下它的特征。它与扩展方法没有直接关系,此行为特定于方法重载解析。扩展方法只是它的一个特例,当然是一个棘手的情况。

找到方法重载匹配并不是特别棘手,当重载不明确时,它会生成一条不错的错误消息,这才是问题所在。关于更改的行为非常清楚的一件事是编译器现在更加彻底。它坚持要知道一切关于参数的类型。即使程序员很清楚传递的参数不可能与另一个未引用的程序集中的类型匹配。但编译器对此很顽固,如果它不知道类型,那么它会坚持你添加引用。

扩展方法很棘手,因为可能有很多,而不仅仅是您(显然)期望选择的 SourceLeadConfigurationHelper.GetLeads() 。一次集会might定义其他扩展方法,它们只是might向 SourceLeadConfiguration 类型添加更多扩展方法。如果编译器知道程序集存在,但不知道它是什么样子,因此无法知道它可能包含哪些扩展方法,那么它会抱怨。请注意,这解释了为什么直接调用静态方法时不会出现错误,编译器不需要去寻找扩展。

您肯定可以猜到编译器如何找到 System.Windows.Forms 程序集。它是由另一个程序集引入的,即您提到但没有描述的程序集。诊断结果是 System.Windows.Forms.Control 类型在该程序集的元数据中泄漏。通常作为公共方法的参数或返回类型。您必须在源代码中进行一些挖掘才能找到它,否则您可以轻松消除它。


关于扩展方法的另一个细节是might与此相关的是,ExtensionAttribute 类型在 .NET 4.5 中从 System.Core.dll 移至 mscorlib.dll。这是一项相当重大的更改,并且当程序员没有正确构建程序集时会导致很多问题。如果您的目标是 .NET 4.0,那么您需要仔细检查这一点,详细信息are here https://stackoverflow.com/a/13750130/17034.


希望您能从引用 Winforms 的程序集中找到它。如果没有,或者您无法消除暴露,那么添加引用实际上就足以让编译器满意。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

扩展方法调用不会编译,但对相同代码的静态方法调用会编译 的相关文章

  • 如何读取扩展文件属性/文件元数据

    因此 我按照教程使用 ASP net core 将文件 上传 到本地路径 这是代码 public IActionResult About IList
  • C++ 中本地类中的静态成员变量?

    我知道我们不能宣布static本地类中的成员变量 但其原因尚不清楚 那么请问有人可以解释一下吗 另外 为什么我们不能访问非static函数内部定义的变量 内部已经定义了局部类 直接在局部类成员函数中 在下面给出的代码中 int main i
  • Unix网络编程澄清

    我正在翻阅这本经典书籍Unix网络编程 https rads stackoverflow com amzn click com 0139498761 当我偶然发现这个程序时 第 6 8 节 第 179 180 页 include unp h
  • 向 Nhibernate 发出 SQL 查询

    如何将此 SQL 查询发送给 Nhibernate SELECT Customer name FROM Company INNER JOIN Customer ON Company CompanyId Customer CompanyId
  • 启动时出现 OData v4 错误:找不到段“Whatever”的资源

    我正在构建新的 v4 服务 一切进展顺利 直到我为新模型 实体添加了新控制器 并在启动站点进行测试运行时收到此错误 控制器似乎编码正确 就像其他控制器一样 控制器 CustomersOData 中的操作 GetFeed 上的路径模板 Cus
  • XamlReader.Load 在后台线程中。是否可以?

    WPF 应用程序具有从单独的文件加载用户控件的操作 使用XamlReader Load method StreamReader mysr new StreamReader pathToFile DependencyObject rootOb
  • 使用 C 语言使用 strftime() 获取缩写时区

    我看过this https stackoverflow com questions 34408909 how to get abbreviated timezone and this https stackoverflow com ques
  • 关于在 Windows 上使用 WiFi Direct Api?

    我目前正在开发一个应用程序 我需要在其中创建链接 阅读 无线网络连接 在桌面应用程序 在 Windows 10 上 和平板电脑 Android 但无关紧要 之间 工作流程 按钮 gt 如果需要提升权限 gt 创建类似托管网络的 WiFi 网
  • 如何在 Linq 中获得左外连接?

    我的数据库中有两个表 如下所示 顾客 C ID city 1 Dhaka 2 New york 3 London 个人信息 P ID C ID Field value 1 1 First Name Nasir 2 1 Last Name U
  • 将 Excel 导入到 Datagridview

    我使用此代码打开 Excel 文件并将其保存在 DataGridView 中 string name Items string constr Provider Microsoft Jet OLEDB 4 0 Data Source Dial
  • 批量更新 SQL Server C#

    我有一个 270k 行的数据库 带有主键mid和一个名为value 我有一个包含中值和值的文本文件 现在我想更新表格 以便将每个值分配给正确的中间值 我当前的方法是从 C 读取文本文件 并为我读取的每一行更新表中的一行 必须有更快的方法来做
  • 如何编写一个同时需要请求和响应Dtos的ServiceStack插件

    我需要提供本地化数据服务 所有本地化的响应 Dto 都共享相同的属性 IE 我定义了一个接口 ILocalizedDto 来标记那些 Dto 在请求端 有一个ILocalizedRequest对于需要本地化的请求 Using IPlugin
  • 等待线程完成

    private void button1 Click object sender EventArgs e for int i 0 i lt 15 i Thread nova new Thread Method nova Start list
  • std::async 与重载函数

    可能的重复 std bind 重载解析 https stackoverflow com questions 4159487 stdbind overload resolution 考虑以下 C 示例 class A public int f
  • 如何从main方法调用业务对象类?

    我已将代码分为业务对象 访问层 如下所示 void Main Business object public class ExpenseBO public void MakeExpense ExpensePayload payload var
  • C++ 密码屏蔽

    我正在编写一个代码来接收密码输入 下面是我的代码 程序运行良好 但问题是除了数字和字母字符之外的其他键也被读取 例如删除 插入等 我知道如何避免它吗 特q string pw char c while c 13 Loop until Ent
  • 英特尔 Pin 与 C++14

    问题 我有一些关于在 C 14 或其他 C 版本中使用英特尔 Pin 的问题 使用较新版本从较旧的 C 编译代码很少会出现任何问题 但由于 Intel Pin 是操作指令级别的 如果我使用 C 11 或 C 14 编译它 是否会出现任何不良
  • Linq-to-entities,在一个查询中获取结果+行数

    我已经看到了有关此事的多个问题 但它们已经有 2 年 或更长 的历史了 所以我想知道这方面是否有任何变化 基本思想是填充网格视图并创建自定义分页 所以 我还需要结果和行数 在 SQL 中 这将类似于 SELECT COUNT id Id N
  • 使用 GhostScript.NET 打印 PDF DPI 打印问题

    我在用GhostScript NET http ghostscriptnet codeplex com打印 PDF 当我以 96DPI 打印时 PDF 打印效果很好 但有点模糊 如果我尝试以 600DPI 打印文档 打印的页面会被极大地放大
  • 在客户端系统中安装后桌面应用程序无法打开

    我目前正在使用 Visual Studio 2017 和 4 6 1 net 框架 我为桌面应用程序创建了安装文件 安装程序在我的系统中完美安装并运行 问题是安装程序在其他计算机上成功安装 但应用程序无法打开 edit 在客户端系统中下载了

随机推荐