何时使用扩展方法?

时间:2017-10-27 06:19:19

标签: c# kotlin extension-methods

我正在编写Kotlin代码,其中一个功能是扩展方法,除了您使用的语法看起来像实例方法调用之外,它们与普通函数有效。

正常功能

fun blah(x: Int) { println(x) }
val f = blah(1)

扩展方法

fun Int.blah() { println(this) }
val f = 1.blah()

据我了解,C#扩展方法的工作方式类似。

原则上,通过将第一个参数的类型移动到函数名称的左侧并相应地调整函数体和调用站点(如本例所示),字面上可以将任何非空函数写为扩展方法。

我应该将所有函数都写为扩展方法吗?他们都没有?我应该使用什么原则来决定要正常写入哪些函数,以及将哪些函数写为其中一个输入的扩展方法?

3 个答案:

答案 0 :(得分:0)

https://kotlinlang.org/docs/reference/extensions.html#extensions-are-resolved-statically

  

扩展程序已静态解决

     

扩展实际上并不修改它们扩展的类。通过定义   扩展,您不会将新成员插入到类中,而只是生成   新函数可以使用点符号对此变量进行调用   类型。

     

我们想强调扩展功能是静态,即它们不是接收器类型的虚拟

因此,将所有函数编写为扩展方法并不是一种好方法,因为它们是静态调度的。这消除了覆盖它们的能力,例如在派生类中。

当您制作扩展功能或正常情况时,它更像是一种设计选择。功能

我会向您推荐以下内容: 每当你有一个函数,你可以用像StringUtil.isNullOrEmpty(String)这样的实用程序类编写实用程序函数时,使用扩展函数。使用其余部分作为"正常"功能

另请阅读Kotlin创建扩展程序的动机: https://kotlinlang.org/docs/reference/extensions.html#motivation

答案 1 :(得分:0)

当您无法访问源代码时,您可以编写扩展名。在Java中,您编写实用程序类。

public final class BarUtility {
    public static int foo(Bar i, int j){
        return i.value + j;
    }
}

BarUtility.foo(bar, 1);

在Kotlin中,你编写了扩展方法。

fun Bar.foo(i: Int): Int = value + i
bar.foo(1)

在C#中,它是相同的,但您也将它用于接口方法实现。 (Kotlin允许实现接口方法。)

答案 2 :(得分:0)

没有固定的规则,但您不应将所有正常功能都写为扩展方法。

它们主要用于两件事:

扩展您无法直接控制的类型。 C#中的一个常见示例是ForEach()函数,该函数使用一种方法将IEnumerable(列表的基本类型等)扩展到所有项目:

public static void ForEach<T>(this IEnumerable<T> enumeration, Action<T> action)
{
     foreach (T item in enumeration)
     {
        action(item);
     }
}

帮助函数简化了对您自己的类的常见调用,但不保证您的类中有自己的方法,或者您不希望成为API的一部分。