2017-04-18 15 views
2

コトルのジェネリック型のインスタンスを取得する最良の方法は何ですか?コトルのジェネリック型のインスタンス化

public T GetValue<T>() where T : new() { 
    return new T(); 
} 
+3

メソッドのパラメータとして '() - > T'を受け取ります。 –

+2

'T'が引数なしのコンストラクタを持つことを保証することはできないので、一般的に、そのようなコードを使用する場所であればどこでも'() - > T 'を渡すことがベストプラクティスと考えられます。 –

+2

@ YoavSternbergあなたは20秒で私を打ち負かしました:) –

答えて

2

はEDIT:コメントで述べたように、これはおそらく悪い考えである私は、次のC#コードの(100%完璧ではない場合)最良の近似を見つけることを期待しています。おそらくこれを達成する最も合理的な方法は、() -> Tを受け入れることです。つまり、必ずしも最も慣習的な方法ではないにしても、あなたが探しているものを達成するための技術は次のとおりです。

残念ながら、あなたはそれを直接達成することはできません.KotlinはJavaの祖先によって挫折しているため、実行時にジェネリックが消去されます。つまり、Tはもはや直接利用できません。反射やインライン関数を使用して、あなたは、しかし、この問題を回避することができます

:我々はいくつかのサンプルのクラスを追加する場合

/* Convenience wrapper that allows you to call getValue<Type>() instead of of getValue(Type::class) */ 
inline fun <reified T: Any> getValue() : T? = getValue(T::class) 

/* We have no way to guarantee that an empty constructor exists, so must return T? instead of T */ 
fun <T: Any> getValue(clazz: KClass<T>) : T? { 
    clazz.constructors.forEach { con -> 
     if (con.parameters.size == 0) { 
      return con.call() 
     } 
    } 
    return null 
} 

は、あなたが、これは空のコンストラクタが存在する場合にインスタンスを返すか、そうでない場合はnullになることがわかります

class Foo() {} 
class Bar(val label: String) { constructor() : this("bar")} 
class Baz(val label: String) 

fun main(args: Array<String>) { 
    System.out.println("Foo: ${getValue<Foo>()}") // [email protected] 
    // No need to specify the type when it can be inferred 
    val foo : Foo? = getValue() 
    System.out.println("Foo: ${foo}") // [email protected] 
    System.out.println("Bar: ${getValue<Bar>()}") // Prints [email protected] 
    System.out.println("Baz: ${getValue<Baz>()}") // null 
} 
関連する問題