.NET 2.0中具有扩展属性的Escape Catch-22 [英] Escape Catch-22 with extension attributes in .NET 2.0

查看:141
本文介绍了.NET 2.0中具有扩展属性的Escape Catch-22的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

How can a single .NET assembly, targeting 2.0, 3.0, 3.5, 4.0, and 4.5 concurrently, support extension methods for both C# and VB.NET consumers?

标准建议是添加以下内容:

The standard suggestion is to add this:

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

此方法由多于一位Microsoft员工,甚至在 MSDN杂志广泛许多博客都认为没有不良影响。

This the approach suggested by more than one Microsoft employee and was even featured in MSDN magazine. It's widely hailed by many bloggers as having 'no ill effects'.

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

Oh, except it will cause a compiler error from a VB.NET project targeting .NET 3.5 or higher.

Microsoft.Core.Scripting.dll的作者 ,然后将 public更改为 internal。

The authors of Microsoft.Core.Scripting.dll figured it out, and changed 'public' to 'internal'.

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

来解决VB兼容性问题。

Which seemed to solve the VB compatibility issue.

因此,我很信任地将这种方法用于广泛使用的ImageResizing.Net库

So I trustingly used that approach for the latest version (3.2.1) of the widely-used ImageResizing.Net library.

但是然后,我们开始得到这个某些情况下,编译器错误(原始报告)或多或少是随机的使用者定位到.NET 3.5 +。

But then, we start getting this compiler error (original report), more or less randomly, for certain users targeting .NET 3.5+.

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

因为MSBuild / VisualStudio编译器显然在解析命名时不会理会作用域规则冲突,并且程序集引用的顺序起着不完全道理的作用,我不完全理解为什么以及何时发生这种情况。

Because the MSBuild/VisualStudio compiler apparently doesn't bother to look at scoping rules when resolving naming conflicts, and the order of assembly references plays a not-quite-docuemented role, I don't fully understand why and when this happens.

有一个很少有变通办法,例如更改程序集名称空间,重新创建项目文件,删除/读取System.Core以及摆弄目标版本.NET框架。不幸的是,所有这些变通办法都不是100%(别名除外,但这是不可接受的痛苦)。

There are a few hacky workarounds, like changing the assembly namespace, recreating the project file, deleting/readding System.Core, and fiddling with the target version of the .NET framework. Unfortunately, none of those workarounds are 100% (except aliasing, but that's an unacceptable pain).

如何在同时解决此问题


  1. 维护对程序集中扩展方法使用的支持,

  2. 维护对.NET 2.0 / 3.0的支持

  3. 每个.NET Framework版本不需要多个程序集。

或者,是否有一个修补程序让编译器注意范围规则?

Or, is there a hotfix to make the compiler pay attention to scoping rules?

关于SO的相关问题未解决此问题

Related questions on SO that don't answer this question

  • C# Extension methods in .NET 2.0
  • Using Extension Methods with .NET Framework 2.0
  • strange warning about ExtensionAttribute
  • Ambigious reference for ExtensionAttribute when using Iron Python in Asp.Net
  • Should I support .NET 2.0?
  • Using extension methods in .NET 2.0?

推荐答案

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

We ran into the same issue with IronPython. http://devhawk.net/2008/10/21/the-fifth-assembly/

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

We ended up moving our custom version of ExtensionAttribute to its own assembly. That way, customers could choose between referencing our custom ExtensionAttribute assembly or System.Core - but never both!

另一件棘手的事情是,即使您不在项目中引用它,也必须始终部署ExtensionAttribute程序集。您的公开扩展方法的项目程序集将具有对该自定义ExtensionAttribute程序集的assemblyref,因此,如果找不到它,CLR将感到不高兴。

The other tricky thing is that you have to always deploy the ExtensionAttribute assembly - even if you don't reference it in your project. Your project assemblies that expose extension methods will have an assemblyref to that custom ExtensionAttribute assembly, so CLR will get upset if it can't be found.

鉴于.NET 2.0支持,我认为最好的选择是根本不使用扩展方法。我对ImageResizer项目不熟悉,但听起来这是ImageResizer的最新更改。将扩展方法更改为传统的静态方法有多可行?我们实际上已经为IronPython / DLR考虑了这一点,但这是不可行的(当时我们与LINQ合并,并且LINQ实质上完全使用了扩展方法)。

Given the hard requirement of .NET 2.0 support, I would think the best bet would be to simply not use extension methods at all. I'm not familiar with the ImageResizer project, but it sounds like this was a recent change in ImageResizer. How feasible would it be to change the extension methods to traditional static methods? We actually thought about that for IronPython/DLR, but it wasn't feasible (We were merged with LINQ at that point and LINQ had made heavy use of extension methods for essentially its entire existence).

这篇关于.NET 2.0中具有扩展属性的Escape Catch-22的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆