A developer on my current project is creating a code generator and wondered how to emit extension methods. It turns out this is really easy.
All you have to do is emit a System.Runtime.CompilerServices.ExtensionAttribute on your static method and the class that contains it. Then just construct the method like a regular static method where the first parameter is the type you want to add the extension to. For example, to emit something like:
public static class StringExtensions {
public static string SayHi(this string instance)
{ ... }
}
you can emit:
[Extension]
public static class StringExtensions {
[Extension]
public static string SayHi(string instance)
{ ... }
}
Then make sure you reference System.Core.dll in your compiler options and everything will work fine.
How would you do this in VB, considering that VB only allows extension methods in Modules, not Classes?
ReplyDeleteI don't know enough VB to help you here, sorry.
ReplyDeleteCorrect me if I'm wrong, but I thought it was not possible to emit a static class with CodeDom.
ReplyDeleteI have an old sample application for this that does this:
ReplyDeleteclassDecl.Attributes = MemberAttributes.Public | MemberAttributes.Static;
where classDecl is a CodeTypeDeclaration.
Looking at the generated assembly in Reflector, the class doesn't actually end up static. I think what we can conclude from this is that a. you are right - you can't do static classes in CodeDom, but b. it doesn't matter - the extension methods having to be in a static class is only a C# compile-time limitation - if you reference the generated assembly and it has the right attributes (regardless of whether the class is static), the extension methods work as expected.