Static Extension Methods

Static extension methods

In short, no, you can't.

Long answer, extension methods are just syntactic sugar. IE:

If you have an extension method on string let's say:

public static string SomeStringExtension(this string s)
{
//whatever..
}

When you then call it:

myString.SomeStringExtension();

The compiler just turns it into:

ExtensionClass.SomeStringExtension(myString);

So as you can see, there's no way to do that for static methods.

And another thing just dawned on me: what would really be the point of being able to add static methods on existing classes? You can just have your own helper class that does the same thing, so what's really the benefit in being able to do:

Bool.Parse(..)

vs.

Helper.ParseBool(..);

Doesn't really bring much to the table...

Can I add extension methods to an existing static class?

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" );
}
}

Why can't I call an extension method as a static method when using static import?

Because of language design:

Using static makes extension methods declared in the specified type
available for extension method lookup. However, the names of the
extension methods are not imported into scope for unqualified
reference in code.

using Directive

c# extend String Class with static method

No, you can't.

For more information, and an explanation, see these earlier questions:

  • Can I add extension methods to an existing static class?
  • Static extension methods
  • Why aren't C# static class extension methods supported?

How to create a static extension method in Dart?

The docs mean that the extension classes themselves can have static fields and helper methods. These won't be extensions on the extended class. That is, in your example, Foo.foo() is legal but String.foo() is not.

You currently cannot create extension methods that are static. See https://github.com/dart-lang/language/issues/723.

Note that you also might see Dart extension methods referred to as "static extension methods", but "static" there means that the extensions are applied statically (i.e., based on the object's type known at compilation-time, not its runtime type).

Extension Methods vs Instance Methods vs Static Class

You asked, "If you could accomplish the desired outcome by simply placing a method in a class definition, why would a POCO combined with either a static helper class or an extension method be preferable?"

The answer is that it depends on the situation, and if the methods in question are directly related to your class' primary concern (see single responsibility principle).

Here are some examples of where it might be a good idea to use each type of approach/method (using your code sample as a starting point).

1. Instance Methods

//This all makes sense as instance methods because you're 
//encapsulating logic MyPoint is concerned with.
public class MyPoint
{
public double x { get; set; }
public double y { get; set; }

public double? DistanceFrom(MyPoint p)
{
if (p != null)
return Math.Sqrt(Math.Pow(this.x - p.x, 2) + Math.Pow(this.y - p.y, 2));
return null;
}
}

2. Static Class Methods - An error logging example.

    //Your class doesn't directly concern itself with logging implmentation;
//that's something that is better left to a separate class, perhaps
//a "Logger" utility class with static methods that are available to your class.
public double? DistanceFrom(MyPoint p)
{
try
{
if (p != null)
return Math.Sqrt(Math.Pow(this.x - p.x, 2) + Math.Pow(this.y - p.y, 2));
return null;
}
catch(Exception ex)
{
//**** Static helper class that can be called from other classes ****
Logger.LogError(ex);

//NOTE: Logger might encapsulate other logging methods like...
//Logger.LogInformation(string s)
//...so an extension method would be less natural, since Logger
//doesn't relate to a specific base type that you can create an
//extension method for.
}
}

3. Extension Methods - An XML serialization example.

//Maybe you want to make it so that any object can XML serialize itself
//using an easy-to-use, shared syntax.
//Your MyPoint class isn't directly concerned about XML serialization,
//so it doesn't make sense to implement this as an instance method but
//MyPoint can pick up this capability from this extension method.
public static class XmlSerialization
{
public static string ToXml(this object valueToSerialize)
{
var serializer = new XmlSerializer(valueToSerialize.GetType());
var sb = new StringBuilder();
using (var writer = new StringWriter(sb))
serializer.Serialize(writer, valueToSerialize);

return sb.ToString();
}
}

//example usage
var point = new MyPoint();
var pointXml = point.ToXml(); //<- from the extension method

The rule of thumb is:

  1. If the method relates to a class' primary concern, put it in an instance method.
  2. If you have a generic utility that might be useful to multiple classes, consider putting it in a static class' method.
  3. If you have a situation similar to 2, but related to a single base type, or you think the code would look cleaner/more concise without having to separately reference a static class, consider an extension method.

Static extension methods in Kotlin

To achieve Uber.doMagic(context), you can write an extension to the companion object of Uber (the companion object declaration is required):

class Uber {
companion object {}
}

fun Uber.Companion.doMagic(context: Context) { }

Why must C# extension methods be defined in static classes?

This is more of an observation than an answer, but...

When you call an instance method, a reference to the object you are calling is pushed onto the stack as the first argument in your method call. That first argument is "this" and is done implicitly.

When you define an extension method, you explicitly define a "this" as the first argument.

Is it possible that method resolution would be confusing if you could define extension methods and instance methods in the same class i.e. defining methods with the same name and, in effect, the same parameters when the "this" parameter is included.

Can you add extension methods that you call like static methods?

According to Microsoft, "Extension methods are a special kind of static method, but they are called as if they were instance methods on the extended type".

Yes, extension methods are static methods. They can all be called in the normal way as static methods, as extension instance methods on the type they "extend", and they can even be called as extension methods on a null reference.

For example:

public static class Extensions {
public static bool IsNullOrEmpty(this string theString) {
return string.IsNullOrEmpty(theString);
}
}

// Code elsewhere.
string test = null;
Console.WriteLine(test.IsNullOrEmpty()); // Valid code.
Console.WriteLine(Extensions.IsNullOrEmpty(test)); // Valid code.

Edit:

Is there a way to add an extension method that it called as if it was a static method?

Do you mean you want to call, for example, string.MyExtensionMethod()? In this case, no, there is no way to do that.



Related Topics



Leave a reply



Submit