9

2.0、3.0、3.5、4.0、および4.5を同時に対象とする単一の.NETアセンブリで、C#とVB.NETの両方のコンシューマーの拡張メソッドをサポートするにはどうすればよいですか?

標準的な提案はこれを追加することです:

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

このアプローチは、複数のMicrosoft従業員によって提案され、MSDNマガジンも取り上げられました。多くのブロガーから「悪影響がない」と広く歓迎されています。

ああ、それが.NET3.5以降を対象とするVB.NETプロジェクトからのコンパイラエラーを引き起こすことを除いて。

Microsoft.Core.Scripting.dllの作成者はそれを理解し、「public」を「internal」に変更しました。

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

これはVBの互換性の問題を解決したようです。

そのため、広く使用されているImageResizing.Netライブラリの最新バージョン(3.2.1)に対して、このアプローチを信頼して使用しました。

しかし、その後、.NET 3.5以降を対象とする特定のユーザーに対して、このコンパイラエラー(元のレポート)が多かれ少なかれランダムに発生し始めます。

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

MSBuild / VisualStudioコンパイラは、名前の競合を解決するときにスコープルールを気にしないようであり、アセンブリ参照の順序は十分に文書化されていない役割を果たしているため、これが発生する理由と時期を完全には理解していません。

アセンブリ名前空間の変更、プロジェクトファイルの再作成、System.Coreの削除/読み取り、ターゲットバージョンの.NET Frameworkの操作など、いくつかの厄介な回避策があります。残念ながら、これらの回避策はいずれも100%ではありません(エイリアシングを除くが、それは許容できない苦痛です)。

どうすればこれを修正できますか

  1. アセンブリ内での拡張メソッドの使用のサポートを維持し、
  2. .NET 2.0/3.0のサポートの維持
  3. .NETFrameworkのバージョンごとに複数のアセンブリを必要としません。

または、コンパイラにスコープ規則に注意を向けさせるための修正プログラムはありますか?

この質問に答えないSOに関する関連質問

4

1 に答える 1

2

IronPythonでも同じ問題が発生しました。http://devhawk.net/2008/10/21/the-fifth-assembly/

最終的に、ExtensionAttributeのカスタムバージョンを独自のアセンブリに移動しました。そうすれば、顧客はカスタムExtensionAttributeアセンブリまたはSystem.Coreのどちらを参照するかを選択できますが、両方を参照することはできません。

もう1つの注意点は、プロジェクトでExtensionAttributeアセンブリを参照していなくても、常にExtensionAttributeアセンブリをデプロイする必要があることです。拡張メソッドを公開するプロジェクトアセンブリには、そのカスタムExtensionAttributeアセンブリへのassemblyrefがあるため、CLRが見つからない場合は、CLRが混乱します。

.NET 2.0サポートの厳しい要件を考えると、最善の策は、拡張メソッドをまったく使用しないことだと思います。私はImageResizerプロジェクトに精通していませんが、これはImageResizerの最近の変更であるように思われます。拡張メソッドを従来の静的メソッドに変更することはどの程度実現可能でしょうか?実際にIronPython/DLRについて考えましたが、実現可能ではありませんでした(その時点で、LINQと統合され、LINQは本質的にその存在全体に対して拡張メソッドを多用していました)。

于 2012-06-20T05:13:34.950 に答える