Wednesday, February 11, 2009

Extension Methods and CodeDom

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.

4 comments:

  1. How would you do this in VB, considering that VB only allows extension methods in Modules, not Classes?

    ReplyDelete
  2. I don't know enough VB to help you here, sorry.

    ReplyDelete
  3. Anonymous4:10 PM

    Correct me if I'm wrong, but I thought it was not possible to emit a static class with CodeDom.

    ReplyDelete
  4. I have an old sample application for this that does this:

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

    ReplyDelete

Note: Only a member of this blog may post a comment.