Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating extension method using CodeDOM

I'm trying to create an extension method using CodeDOM. There doesn't seem to be any support for them and using ExtensionAttribute (which C# uses internally to mark extension methods) is not allowed.

It's possible to use a trick to specify the this modifier, but how do I make the containing class static, so that the code actually compiles?

Since static is a C# concept, it's not exposed through the CodeDOM API. And setting TypeAttributes to TypeAttributes.Abstract | TypeAttributes.Sealed | TypeAttributes.Public doesn't work, because

an abstract class cannot be sealed or static

How do I make the extension method to compile?

like image 688
svick Avatar asked Oct 14 '25 17:10

svick


2 Answers

I'm pretty sure you're looking for:

var staticClass = new CodeTypeDeclaration("Extensions")
    {
        Attributes = MemberAttributes.Public|MemberAttributes.Static
    };

However, this appears not to work. Interestingly enough:

provider.Supports(GeneratorSupport.StaticConstructors);
// True

provider.Supports(GeneratorSupport.PublicStaticMembers);
// True

But yet when you go and output it, no changes even though the Attributes property clearly changes from 0x00005002 to 0x00006003.

Per Microsoft Connect this is not possible:

Thanks for reporting this. Unfortunately, it doesn't look like we can support static classes for CodeDom.

The reason is that one of the design goals of CodeDom is to be language-independent, so that any code generated for one language can easily be generated for a different language. While static classes are used often in C#, VB does not support them. Therefore, adding support for static classes will mean that some code that can compile for C# won't be compilable for VB, which goes against our goals.

While we can't act on this issue, we ask that you please continue to provide feedback in the future to help us improve.


A dirty workaround:

var type = new CodeTypeDeclaration("Extensions");
type.Attributes = MemberAttributes.Public;
type.StartDirectives.Add(
    new CodeRegionDirective(CodeRegionMode.Start, "\nstatic"));
type.EndDirectives.Add(
    new CodeRegionDirective(CodeRegionMode.End, String.Empty));

Produces:

#region
static
public class Extensions
{
}
#endregion

Which compiles.

like image 65
user7116 Avatar answered Oct 17 '25 09:10

user7116


Instead of compiling the CodeCompileUnit directly, you could get the source code, replace class Extensions with static class Extensions and compile that code.

like image 43
svick Avatar answered Oct 17 '25 08:10

svick



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!