C# Extension methods in .NET 2.0
I have found several links to methods of making extension methods work in .NET2.0 (The moth, Discord & Rhyme, Stack Overflow). I have also heard vaguely from a colleague that this causes some problems with libraries or something? Is this the case? Also all 3 use different methods:
The moth:
namespace System.Runtime.CompilerServices
{
public class ExtensionAttribute : Attri开发者_高级运维bute { }
}
Discord and Rhyme
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
public class ExtensionAttribute : Attribute {}
}
Stack Overflow
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class
| AttributeTargets.Method)]
public sealed class ExtensionAttribute : Attribute {}
}
Whats the difference between these methods, and which one would you recommend?
Ultimately it isn't going to make much difference; you could argue that the one that matches the runtime is preferred, but the ideal answer is to switch to .NET 3.5 (otherwise at a later date it can get confusing with different versions of the same attribute in scope etc).
The [AttributeUsage]
will prevent it being attached to things where it won't do anything - but it won't do aything by itself anyway...
Looking at metadata against the type, the exact attribute usage seems most like the stackoverflow variant - but ultimately this isn't hugely important - the name and namespace is all that matters (and that it inherits from Attribute
).
The difference is simple enough:
In your first example, you can put the attribute anywhere. In the second example, you can only apply it to a method, never more than one to the same method and an inherited class with the method overridden will not inherit the attribute. In the third example, you can apply it to a method, a class or an assembly.
If you try to apply it in any other place, you will get a compiler error.
The second seems to make most sense.
I would recommend Discord and Rhyme because it providing meaningful constraints for how the attribute is supposed to be applied.
- It can only be applied to methods
- You can only apply it once
- The attribute cannot be inherited
Personally, I would recommend avoiding all three. Each option makes this work by performing a "trick" - I would not rely on this for production code.
If you want to use extension methods, upgrade to C# 3.0. Otherwise, just stick to calling the method using the non-extension method syntax.
You can always take an extension method call like so:
public static class Utility {
public static string Extension(this string original) { ... }
// call with:
var newString = myString.Extension();
And call it directly:
string newString = Utility.Extension(myString);
This will be more consistent with C#/.NET 2 syntax, and would be my recommendation.
The SO version is the accurate one, for the pure sake of accuracy you should use it.
Fwiw, the AttributeTarget.Method specifier is crystal clear. Class and Assembly less so. Both the C# and the VB.NET compiler emit the attribute on the static class / Module that contains the extension method. And on the assembly that contains the class / Module. Why they do this is less crystal clear, it wouldn't be needed to properly compile them. I'm guessing this is an optimization at work, helping both the compiler and IntelliSense discover when an extension method should be considered.
Getting the attribute applied to the assembly is actually a problem. That won't work right when you compile code to .netmodules. But that's a very obscure issue.
精彩评论