Escape Catch-22 with extension attributes in .NET 2.0

好久不见. 提交于 2019-12-17 19:38:54

问题


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 { }
}

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'.

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

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

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

Which seemed to solve the VB compatibility issue.

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

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'

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.

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).

How can I fix this while

  1. Maintaining support for extension method use within the assembly,
  2. Maintaining support for .NET 2.0/3.0
  3. Not requiring multiple assemblies for each .NET framework version.

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

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?

回答1:


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

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!

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.

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).



来源:https://stackoverflow.com/questions/11025100/escape-catch-22-with-extension-attributes-in-net-2-0

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!