This question already has answers here:
Can I add extension methods to an existing static class?
(18 answers)
Closed 2 years ago.
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".
Is there a way to add an extension method that it called as if it was a static method? Or to do something else that has the same effect?
Edit:
By which I mean "called as if it was a static method on the extended class".
Sorry for the ambiguity.
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.
Extension methods are static methods. You don't need to do anything.
The only thing that distinguishes an extension method from any other static method is that it can be called as if it were an instance method in addition to being called normally as a static method.
Related
This question already has answers here:
When should one prefer Kotlin extension functions?
(4 answers)
Closed 5 years ago.
I'm writing Kotlin code and one the features it has is extension methods, which are effectively the same as normal functions except the syntax you use looks like an instance method call.
Normal function
fun blah(x: Int) { println(x) }
val f = blah(1)
Extension method
fun Int.blah() { println(this) }
val f = 1.blah()
As far as I understand, C# extension methods work similarly.
In principle, literally any non-nullary function could be written as an extension method by moving the type of the first parameter to the left of the function name and adjusting the function body and call sites accordingly (as in this example).
Should I write all my functions as extension methods, then? None of them? What principle should I use to decide what functions to write normally, and which to write as an extension method of one of the inputs?
https://kotlinlang.org/docs/reference/extensions.html#extensions-are-resolved-statically
Extensions are resolved statically
Extensions do not actually modify classes they extend. By defining an
extension, you do not insert new members into a class, but merely make
new functions callable with the dot-notation on variables of this
type.
We would like to emphasize that extension functions are dispatched statically, i.e. they are not virtual by receiver type
So writing all of your functions as extension methods wouldn't be a good approach because they are dispatched statically. This takes away the ability to override them e.g. in derived classes.
It is more like a design choice when you make a extension function or a "normal" function.
I would recommend you the following:
Whenever you have a function which you would write as an Utility-function with an Utility-class like StringUtil.isNullOrEmpty(String), use extension functions. Use the rest as "normal" functions.
Also read the Kotlin's motivation to create Extensions:
https://kotlinlang.org/docs/reference/extensions.html#motivation
You write extensions when you do not have access of source code. In Java, you write utility classes.
public final class BarUtility {
public static int foo(Bar i, int j){
return i.value + j;
}
}
BarUtility.foo(bar, 1);
In Kotlin, you write extensions method.
fun Bar.foo(i: Int): Int = value + i
bar.foo(1)
In C#, it is the same but you also use it for interface method implementation. (Kotlin allows interface method implementation.)
There is no fixed rule, but you shouldn't write all of your normal functions as extension methods.
They are primarily used for two things:
Extending types that you don't have direct control over. A common example in C# is the ForEach() function that extends IEnumerable (basic types for lists etc.) with a method to apply an action to all items:
public static void ForEach<T>(this IEnumerable<T> enumeration, Action<T> action)
{
foreach (T item in enumeration)
{
action(item);
}
}
Helper functions that simplify common calls to your own classes, but don't warrant an own method in your class or you don't want be part of your API.
This question already has answers here:
Method can be made static, but should it?
(14 answers)
Closed 8 years ago.
Is there any harm or benefit for having instance methods call static methods to do their work?
If your confused by what I mean, take a look at the example code below. StripFormatting is an instance method and static method. If another developer creates an instance of PhoneUtil then all that is needed is for the StripFormatting method to be called on the instance of the object. If a developer decides not to create an instance of PhoneUtil they can call the static method except this method has a parameter for the PhoneNumber.
public string StripFormatting()
{
return PhoneUtil.StripFormatting(this.PhoneNumber);
}
public static string StripFormatting(string psPhoneNumber)
{
string tsPhoneNumber = psPhoneNumber;
Regex toNotDigit = new Regex("\\D+");
tsPhoneNumber = toNotDigit.Replace(tsPhoneNumber, "");
return tsPhoneNumber;
}
Member function or Static methods are chosen based on your software design. There are pros and cons in relation to that design you have chosen.
In general, consider using static methods when that method has no any effect on some type internal state and does not need to store some data inside, in shorts: it's execution only.
In all oher cases conside using instance methods.
Repeat this is a basic idea,as all depends on your design.
For example: looking on the code provided I see that method you wrote can easily be made static.
This question already has answers here:
"this" in function parameter
(5 answers)
Closed 9 years ago.
I want to understand how extension method works?Can we define extension methods in non static classes?
*
Why do we put extension methods inside static class?
*
According to MSDN,
**Their first parameter specifies which type the method operates on, and the parameter is preceded by the this modifier. Extension methods
are only in scope when you explicitly import the namespace into your
source code with a using directive.
**
What is the role of this operator here and how does it associates that extension method to that argument?
No, you can't define an extension method on a class that is not static.
The this is syntactic sugar that allows to call your static extension method on an instance. But at the end of the day, an extension method is nothing more than a static method in a static class.
So basically:
var test = myInstance.MyExtensionMethod();
is the same as
var test = MyExtensionClass.MyExtensionMethod(myInstance);
They are 4 requirements for method to be an extension method:
It has to be declared in static class
It has to be static (which actually is always true if the first one is met)
It has to be public
It has to have first parameter marked with this keyword
So you can't define extension method in non-static class.
Whole Extension Method functionality is some kind of syntax sugar. Following extension method declared on MyClass:
// The following extension methods can be accessed by instances of any
// class that is or inherits MyClass.
public static class Extension
{
public static void MethodA(this MyClass myInterface, int i)
{
Console.WriteLine
("Extension.MethodA(this IMyInterface myInterface, int i)");
}
}
can be called in two ways:
var myClassObject = new MyClass();
Extension.MethodA(myClassObject);
Or
myClassObject.MethodA();
However, the second one will be transformed into the first one by compiler anyway.
What is the role of this operator here and how does it associates that
extension method to that argument?
In this context this is not an operator, it is a modifier. It could have been called something else, it has no relation to this object which refers to the current object within a normal method call.
The role of this modifier is to tell the compiler that this is actually an extension method and not a standard static method, so that it will not complain when you call it in a way which looks like an instance method call, although it is not.
No, extension methods have to be in a static class, that's just the rule. It could have been possible to allow extension methods to be defined anywhere, but to make it easier to find them they are not allowed to be buried inside classes with a lot of other code.
The this keyword is used on the first parameter of an extension method to specify that it is an extension method.
(The internal implementation of a regular method also has a reference to the object as a first parameter, so what the compiler does with extension methods is just to add them to the other methods in the class.)
Can someone explain to me why in the following the 3rd invocation of DoSomething is invalid?
( Error message is "The name 'DoSomething' does not exist in the current context" )
public class A { }
public class B : A
{
public void WhyNotDirect()
{
var a = new A();
a.DoSomething(); // OK
this.DoSomething(); // OK
DoSomething(); // ?? Why Not
}
}
public static class A_Ext
{
public static void DoSomething(this A a)
{
Console.WriteLine("OK");
}
}
Extension methods can be invoked like other static methods.
Change it to A_Ext.DoSomething(this).
If you're asking why it isn't implicitly invoked on this, the answer is that that's the way the spec was written. I would assume that the reason is that calling it without a qualifier would be too misleading.
Because DoSomething takes a parameter.
DoSomething(a) would be legal.
Edit
I read the question a bit wrong here.
Since your calling it a a normal static method, and not a extension method, you need to prefic with the class name.
So A_Ext.DoSomething(a); will work.
If you call it like a normal static method, all the same rules apply.
Your second variant works because B inhetits A, and therefore you still end up calling it as an extension method, but the third does not.
sorry about the first version above that does not work. I'll leave it to keep the comment relevant.
Extension methods are still static methods, not true instance calls. In order for this to work you would need specific context using instance method syntax (from Extension Methods (C# Programming Guide))
In your code you invoke the extension
method with instance method syntax.
However, the intermediate language
(IL) generated by the compiler
translates your code into a call on
the static method. Therefore, the
principle of encapsulation is not
really being violated. In fact,
extension methods cannot access
private variables in the type they are
extending.
So while normally, both syntaxes would work, the second is without explicit context, and it would seem that the IL generated can't obtain the context implicitly.
DoSomething requires an instance of A to do anything, and without a qualifier, the compiler can't see which DoSomething you need to invoke. It doesn't know to check in A_Ext for your method unless you qualify it with this.
I'm a little confused as to why this doesn't give an error. I found this code deep inside of some outdated legacy software and was surprised to see it work.
public static string CleanFileName(this string fileName)
{
return CleanFileName(fileName, 64);
}
public static string CleanFileName(this string fileName, int maxLength)
{
//some logic
}
My experience with extension methods is to call it like this:
fileName.CleanFileName(64);
Does this only work because its a static method as well? Is this common practice and just something I haven't seen yet or a piece of outdated legacy code that I should kill with fire?
Extension methods can always optionally be called as if the "this" modifier was not even there (aka as a normal static method). It's less readable to do this, but syntactically valid.
The other answer is misleading because "It works because the method call is being made from within the same type as its overload." implies something about extension methods. You can invoke extension methods as normal static methods regardless of what class you happen to be in. But through the comments below, it sounds like the confusion is whether the class needs to be qualified or not. And in that vein, Nathan is correct that the reason the class name can be elided is because the call is happening from within the same class as the overload.
It works because the call to CleanFileName(string, int) is being made from within the same type as CleanFileName(string), which allows the call to be made in standard method syntax, rather than extension method syntax. As such, no string instance prefix is required in front of the extension method.
Semantically speaking, static string Foo(this string foo, int bar) { } can be called in the form of Foo(string, int) or string.Foo(int).