2017-10-27 8 views
1

私はKotlinコードを書いていますが、その機能には拡張メソッドがあります。これは、使用する構文をインスタンスメソッド呼び出しのように見せている以外は、通常の関数と実質的に同じです。拡張メソッドはいつ使用しますか?

正常な機能

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

拡張メソッド私の知る限り理解し

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

、C#の拡張メソッドも同様に動作します。

原則として、最初のパラメータの型を関数名の左側に移動し、関数本体を調整してそれに応じてサイトを呼び出すことにより、文字通り任意の非null関数を拡張メソッドとして記述できます(この例のように) 。

すべての機能を拡張メソッドとして記述する必要がありますか?そのなかで何も?どんな機能を正常に書くのか、そして入力の一つの拡張方法として書くのかを決定するために私はどのような原則を使うべきですか?

+0

一般的に、あなたは自分が所有していないオブジェクトを拡張しないでください。 –

+0

@AlexeiLevenkovそれは拡張メソッドと継承についてです。私は、拡張メソッドと通常の関数/静的メソッドについて質問しています。 – Jesse

+1

@MarcusHöglundなぜそれを考えるのですか?拡張機能のスコープを設定することができます。彼らはグローバルではありません。私の意見では、あなたが所有していないクラスにエクステンションを書くことは、エクステンション関数の最良のユースケースの1つです。それは、あなたが読みやすいDSLを書いてみましょう。 – marstran

答えて

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

これはOOPに当てはまりますが、たとえばIEnumerableは[関数プログラミングの原則](https://blogs.msdn.microsoft.com/ericlippert/2009/05/18/foreach-vs-foreach/)に基づいています。静的メソッドを持つのは完全にうまくいきます。 –

+1

同意します。拡張メソッドを使用する必要があるときは、はい/いいえリストはありません。説明したような状況があり、多かれ少なかれそれを使用しなければならない場所や、使用しない場所があります。 – guenhter

0

あなたがソースコードへのアクセスを持っていないときは、拡張子を書いてください。 Javaでは、ユーティリティクラスを作成します。

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

BarUtility.foo(bar, 1); 

エクステンション方式では、

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

C#では、これは同じですが、インターフェイスメソッドの実装にも使用します。 (Kotlinはインタフェースメソッドの実装を可能にします。)

0

固定ルールはありませんが、通常の関数をすべて拡張メソッドとして記述するべきではありません。あなたが直接制御を超える必要はありません

拡張タイプ:

彼らは主に二つのもののために使用されています。独自のクラスに共通の呼び出しを簡素化

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

ヘルパー機能:C#での一般的な例は、すべての項目にアクションを適用する方法でのIEnumerable(リストなどのための基本的なタイプ)を拡張するForEach()関数ですあなたのクラスで独自のメソッドを保証するものでも、APIの一部であることも望まない場合もあります。

関連する問題