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.
Related
For a test, I want to create a generic "helper" method which will take take two arguments, the first argument is a function (or a reference to the function) and the 2nd argument is a list of objects for that function that are to be called as its parameters.
The following does this perfectly:
CallMyFunctionWithParamsPlease(new Func<int, int>(MyMethod), new object[] {1});
public static int CallMyFunctionWithParamsPlease(Delegate func, params object[] args)
{
func.DynamicInvoke(args);
return 3;
}
The thing is, this doesn't look very nice when calling it and I wish to abstract it into another method to act as syntatic sugar.
Ideally I want it to be called like this:
CallMyFunctionWithParamsPlease(myMethod, new Object[] {1});
From what I can gather, there is no elegant solution to do this in C# since I cannot pass myMethod by itself as a reference anywhere, instead I must pass it by declaring a new Func along with the return type of the method. Since I'm not using this return type anywhere, I'm not sure why it's necessary to input this information. My limited understanding is that because C# is statically typed, the compiler must know everything and things like this just aren't possible.
Is this true or not? How would I create syntatic sugar to simply pass a method to another method which can be called there without needing to invoke "new Func"? I would have thought simply passing the function as a reference pointer would allow me to do this, but I'm having difficultly doing this too. I looked into delegates, using "unsafe" with pointers, and a few other options. None of them seem to make this possible, or if they do, they didn't explain it in a manner that I could understand.
I simply want to pass a method to another method, and invoke it with a variable list of object params with variable length whereby I don't need to specify this whilst invoking it. I'm not sure if I'm trying to force C# to do something it's not meant to do here, and instead I'd be better off using a dynamically typed language to do this. The problem is I really enjoy the intellisense that the static typing of C# offers, along with the performance improvements over a language like Python. I'd just like a way to syntactically abstract away the boilerplate with my own helper methods for things like this.
UPDATE: Thanks to the comments here it seems I can do this with a lambda expression nice and elegantly. The signature can be simply changed to public static long CallMyFunctionWithParamsPlease<T>(Func<T> func)
If deferred execution is what you want simply pass a Func<TReturnType> to your method (or class). The calling method doesn't need to know how many parameters are involved.
e.g. Assuming MyMethod has a signature int MyMethod(int arg):
CallMyFunctionWithParamsPlease(() => MyMethod(1));
public static int CallMyFunctionWithParamsPlease(Func<int> func)
{
return func();
}
If MyMethod takes two parameters, it's the same call:
CallMyFunctionWithParamsPlease(() => MyMethod(1, 2));
I've read open source c# code and there is a lot of strange grammar (to me).
They declare method arguments with the this keyword like this:
this object #object
What does it mean?
If I remove 'this' keyword where is before the data type, then will it work differently?
Sounds like an Extension Method.
The # symbol allows the variable name to be the same as a C# keyword - I tend to avoid them like the plague personally.
If you remove the this keyword, it will no longer be an extension method, just a static method. Depending on the calling code syntax, it may no longer compile, for example:
public static class IntegerMethods
{
public static int Add(this int i, int value)
{
return i + value;
}
}
int i = 0;
// This is an "extension method" call, and will only compile against extension methods.
i = i.Add(2);
// This is a standard static method call.
i = IntegerMethods.Add(i, 2);
The compiler will simply translate all "extension method calls" into standard static method calls at any rate, but extension method calls will still only work against valid extension methods as per the this type name syntax.
Some guidelines
These are my own, but I find they are useful.
Discoverability of extension methods can be a problem, so be mindful of the namespace you choose to contain them in. We have very useful stuff under .NET namespaces such as System.Collections or whatever. Less useful but otherwise "common" stuff tends to go under Extensions.<namespace of extended type> such that discoverability is at least consistent via convention.
Try not to extend often used types in broad scope, you don't want MyFabulousExtensionMethod appearing on object throughout your app. If you need to, either constrain the scope (namespace) to be very specific, or bypass extension methods and use a static class directly - these won't pollute the type metadata in IntelliSense.
In extension methods, "this" can be null (due to how they compile into static method calls) so be careful and don't assume that "this" is not null (from the calling side this looks like a successful method call on a null target).
These are optional and not exhaustive, but I find they usually fall under the banner of "good" advice. YMMV.
The 'this type name' syntax is used for extension methods.
For example if I wanted to add a UnCamelCase method to a string (so I could do "HelloWorld".UnCamelCase() to produce "Hello World` - I'd write this:
public static string UnCamelCase(this string text)
{
/*match any instances of a lower case character followed by an upper case
* one, and replace them with the same characters with a space between them*/
return Regex.Replace(text, "([a-z])([A-Z])", "$1 $2");
}
this string text means the specific instance of the string that you're working with, and text is the identifier for it.
The # syntax allows for variable names that are ordinarily reserved.
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.)
While I hate to beat a horse to death on this subject (I've read through various articles about this), but would just like to get more opinions on this matter before I create my "own convention" to use from now on while coding in Objective-C.
The convention that I want to figure out is ultimately how to (using best coding practices for production level code) use private methods in a class. Coming from a background in C#, when I write classes, usually there is a block of code that is repeated in multiple public methods (such as error checking, or WCF service connection setup). I usually create one block of this code and put it in a private method for only these public methods to access. This way if I need to make a change, I only need to do it in one spot, as opposed to 10 different places in a class, but then never giving users the ability to call this private method. For example:
public Class A
{
public void method1()
{
doErrorChecking()
// Do more stuff
}
public void method2()
{
doErrorChecking()
// Do more stuff
}
private doErrorChecking() { //Error Checking Code}
}
I understand that there is no real way to truly make that last method private in Objective-C, but just really want to make sure that when I create all future classes in Objective-C for iOS development I'm following the best practice available so future code refactoring on this matter won't be needed (hopefully). I've noticed people talking about categories, others just don't put the method in the #interface file, and others use extension methods. At the moment I'm just putting the method implementation in the #implementation file, but not the interface file. I'm also making the "wannabe" private method have a really distinct name so that sub-classing or overwriting methods is not an issue. Is this the path I should be following? Or for these particular scenarios is there a better way to do it?
Yes, it's perfectly reasonable to want to extract your functionality out into another method. The best way to do this in my opinion is using a class continuation, which you can put your private method declarations in. It can go above your #implementation block in your .m file, so it's not in the public header.
#interface MyClass ()
- (void)_privateMethod:(id)arg;
#end
The difference between a class continuation and a normal category (such as #interface MyClass (PrivateMethods)) is that the compiler will require you to implement the methods in your main #implementation block, rather than having a separate #implementation MyClass (PrivateMethods) block. This is arguably desirable when implementing helper methods like you described.
In terms of naming, it's relatively common to start private method names (and ivar names, for that matter) with an _, though not everyone does — apparently Apple reserves this for themselves, so you should pick a different prefix. The language doesn't enforce anything.
I would use a class extension, definitely. In the implementation file, include something like this above your #implementation:
#interface A ()
- (void) doErrorChecking;
#end
Then use the method in code as needed. Although due to objective-c's dynamic nature no method is truly private, this will obscure the method from your interface file while still technically including it in your own 'private' interface. In general, keep your .h file for methods and properties that are ok for public use, while limiting private use methods and properties to a class extension in the implementation file.
If you just need a reusable set of code that absolutely cannot be overridden by a subclass, you could just make a regular C function instead of a method. If the function is declared within the scope of the class #implementation block, it can still get access to all the private ivars of the object. You'd need to pass in a pointer to self, though, since a function isn't bound to a particular object
So it would look like this:
static BOOL isInValidState(MyClass *);
#implementation MyClass
static BOOL isInValidState(MyClass *self) {
if (self->somePrivateIvar == nil) {
return NO;
}
if ([self->someString isEqualToString:#"pigsAreFlying"]) {
return NO;
}
return YES;
}
- (void)method1 {
if (isInValidState(self) == NO) {
return;
}
// Do whatever method 1 does
}
- (void)method2 {
if (isInValidState(self) == NO) {
return;
}
// Do whatever method 2 does
}
#end
Since functions are not part of the method list of a class, this error checking method cannot ever be overridden. Since we declared it static, it is only accessible within the scope of this file, which means that it's effectively private; it cannot be called by an object of any other class.
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).