Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I add extension methods to an existing static class?

I'm a fan of extension methods in C#, but haven't had any success adding an extension method to a static class, such as Console.

For example, if I want to add an extension to Console, called 'WriteBlueLine', so that I can go:

Console.WriteBlueLine("This text is blue"); 

I tried this by adding a local, public static method, with Console as a 'this' parameter... but no dice!

public static class Helpers {     public static void WriteBlueLine(this Console c, string text)     {         Console.ForegroundColor = ConsoleColor.Blue;         Console.WriteLine(text);         Console.ResetColor();     } } 

This didn't add a 'WriteBlueLine' method to Console... am I doing it wrong? Or asking for the impossible?

like image 923
Leon Bambrick Avatar asked Oct 30 '08 03:10

Leon Bambrick


People also ask

Why do extension methods need to be in a static class?

It is compulsion that the Extension method must be in a Static class only so that only one Instance is created. For example, if you place the following in ASP.Net page it will not work. Though error will not come, but you will not see the method available.

Can extension methods extend non static classes?

Actually I'm answering the question of why extension methods cannot work with static classes. The answer is because extension methods are compiled into static methods that cannot recieve a reference to a static class.

Can we add extension method to sealed class?

You can't prevent it - there's no keyword to put on your class to stop this feature. If you have a class - someone can write an extension method for it. But why is this such a problem?

Are extension methods always static?

Extension methods can only be declared in non-generic, non-nested static classes. The first parameter of an extension method can have no modifiers other than this, and the parameter type cannot be a pointer type.


2 Answers

No. Extension methods require an instance variable (value) for an object. You can however, write a static wrapper around the ConfigurationManager interface. If you implement the wrapper, you don't need an extension method since you can just add the method directly.

 public static class ConfigurationManagerWrapper  {       public static ConfigurationSection GetSection( string name )       {          return ConfigurationManager.GetSection( name );       }        .....        public static ConfigurationSection GetWidgetSection()       {           return GetSection( "widgets" );       }  } 
like image 153
tvanfosson Avatar answered Sep 28 '22 09:09

tvanfosson


Can you add static extensions to classes in C#? No but you can do this:

public static class Extensions {     public static T Create<T>(this T @this)         where T : class, new()     {         return Utility<T>.Create();     } }  public static class Utility<T>     where T : class, new() {     static Utility()     {         Create = Expression.Lambda<Func<T>>(Expression.New(typeof(T).GetConstructor(Type.EmptyTypes))).Compile();     }     public static Func<T> Create { get; private set; } } 

Here's how it works. While you can't technically write static extension methods, instead this code exploits a loophole in extension methods. That loophole being that you can call extension methods on null objects without getting the null exception (unless you access anything via @this).

So here's how you would use this:

    var ds1 = (null as DataSet).Create(); // as oppose to DataSet.Create()     // or     DataSet ds2 = null;     ds2 = ds2.Create();      // using some of the techniques above you could have this:     (null as Console).WriteBlueLine(...); // as oppose to Console.WriteBlueLine(...) 

Now WHY did I pick calling the default constructor as an example, and AND why don't I just return new T() in the first code snippet without doing all of that Expression garbage? Well todays your lucky day because you get a 2fer. As any advanced .NET developer knows, new T() is slow because it generates a call to System.Activator which uses reflection to get the default constructor before calling it. Damn you Microsoft! However my code calls the default constructor of the object directly.

Static extensions would be better than this but desperate times call for desperate measures.

like image 25
Mr. Obnoxious Avatar answered Sep 28 '22 10:09

Mr. Obnoxious