C# 3.0から導入された拡張メソッドを使用するにはSystem.Core.dllを参照に追加する必要がある。 これは拡張メソッドを含むコードをコンパイルする際に、System.Core.dllのSystem.Runtime.CompilerServices.ExtensionAttributeを参照するため。
しかし、ExtensionAttributeはSystem.Core.dllで宣言されている必要は無く、コンパイル時に同名の属性が参照できればよいので、ExtensionAttributeを自前で宣言すればSystem.Core.dllを参照することなく拡張メソッドを含むコードをコンパイルできるようになる。
ExtensionAttributeの宣言
ExtensionAttributeを自前で宣言する場合、
- 名前空間はSystem.Runtime.CompilerServicesでなければならない(VBの場合、暗黙的な名前空間は使用しない)
- AttributeUsageは少なくともAttributeTargets.Assembly, AttributeTargets.Class, AttributeTargets.Methodの三つを含む必要がある(このうち一つでも省略した場合エラーとなる)
の二点に注意する必要がある。
コンパイル・実行すると次のようになる。 コンパイルオプション /noconfig を付けないとコンパイラが自動的にSystem.Core.dllへの参照を含めてしまうので注意。
このようにすることでSystem.Core.dllを参照する必要がなくなるため、拡張メソッドを含むコードでも.NET Framework 2.0をターゲットとしてコンパイルできるようになる。
System.Core.dllのExtensionAttributeとの衝突
このようにして宣言したExtensionAttributeが存在する状態でSystem.Core.dllを参照に含めてコンパイルすると、System.Core.dllのExtensionAttributeと自前のものが衝突することになる。 例えばコンパイルオプション /noconfig を付けずにコンパイルすると衝突が起こるが、仮にExtensionAttributeが衝突しても警告(CS1685)となるだけでエラーにはならない。
System.Core.dllを参照する場合でもコンパイルオプションに /nowarn:1685 を指定すればこの警告は表示されなくなる。
ソース中に #pragma warning disable 1685 と記述してもこの警告は抑止できない。