【问题标题】:Escape Catch-22 with extension attributes in .NET 2.0在 .NET 2.0 中使用扩展属性转义 Catch-22
【发布时间】:2012-06-17 00:20:18
【问题描述】:

单个 .NET 程序集如何同时针对 2.0、3.0、3.5、4.0 和 4.5 支持 C# 和 VB.NET 使用者的扩展方法?

标准建议是添加这个:

namespace System.Runtime.CompilerServices
{
  public sealed class ExtensionAttribute : Attribute { }
}

这是moreone Microsoft employee 建议的方法,甚至在MSDN magazine 中也有特色。 widelymany bloggers 誉为“没有不良影响”。

哦,除非它会导致针对 .NET 3.5 或更高版本的 VB.NET 项目出现编译器错误。

Microsoft.Core.Scripting.dll figured it out 的作者,并将“public”更改为“internal”。

namespace System.Runtime.CompilerServices
{
  internal sealed class ExtensionAttribute : Attribute { }
}

这似乎解决了 VB 兼容性问题。

因此,我信任地将这种方法用于widely-used ImageResizing.Net library 的最新版本 (3.2.1)。

但是那么,对于某些面向 .NET 3.5+ 的用户,我们开始收到此编译器错误 (original report),或多或少是随机的。

Error 5 Missing compiler required member
'System.Runtime.CompilerServices.ExtensionAttribute..ctor'

因为 MSBuild/VisualStudio 编译器在解决命名冲突时显然不会费心查看范围规则,而且程序集引用的顺序所起的作用并没有完全记录下来,所以我不完全理解为什么以及何时会发生这种情况.

有一个few hacky workarounds,比如更改程序集命名空间、重新创建项目文件、删除/读取 System.Core,以及摆弄 .NET 框架的目标版本。不幸的是,这些变通方法都不是 100%(别名除外,但这是一种无法接受的痛苦)。

我该如何解决这个问题

  1. 维护对在程序集中使用扩展方法的支持,
  2. 保持对 .NET 2.0/3.0 的支持
  3. 每个 .NET 框架版本不需要多个程序集。

或者,有没有让编译器注意作用域规则的修补程序?

未回答此问题的关于 SO 的相关问题

【问题讨论】:

  • 呃。您的赏金缺少零。最好通过 Microsoft 支持来解决这个问题,尽管他们可能会以“不支持”来驳回它。

标签: clr extension-methods csc vbc


【解决方案1】:

我们在 IronPython 上遇到了同样的问题。 http://devhawk.net/2008/10/21/the-fifth-assembly/

我们最终将 ExtensionAttribute 的自定义版本移到了它自己的程序集中。这样,客户可以在引用我们的自定义 ExtensionAttribute 程序集或 System.Core 之间进行选择 - 但不能同时引用两者!

另一个棘手的问题是您必须始终部署 E​​xtensionAttribute 程序集 - 即使您没有在项目中引用它。公开扩展方法的项目程序集将具有该自定义 ExtensionAttribute 程序集的 assemblyref,因此如果找不到,CLR 会感到不安。

鉴于对 .NET 2.0 支持的严格要求,我认为最好的选择是根本不使用扩展方法。我不熟悉 ImageResizer 项目,但听起来这是 ImageResizer 的最新变化。将扩展方法更改为传统的静态方法有多可行?实际上,我们曾为 IronPython/DLR 考虑过这一点,但这并不可行(当时我们与 LINQ 合并,而 LINQ 基本上在其整个存在过程中都大量使用了扩展方法)。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多