2017-09-12 4 views
0

注釈を持つすべてのプロパティの値を使用します。ほとんどの場合、私のコードは機能しますが、私はすべてのプロパティを取得し、その注釈を持つものだけを取ります。リフレクションでプロパティの値を取得する方法

private inline fun <reified A : Annotation> (target: Any) { 
    target::class.memberProperties 
       .filter { it.annotations.any { annotation -> annotation is A } } 
       .forEach { 
        // How do I get the value here? 
       } 
} 

私はit.get(...)を使用していたが、パラメータとしてNothingget期待しています。 getterでも同じです。 it.call(target)を呼び出すことはできますが、呼び出す方法がわからないアクセルgetがあるので間違っています。

プロパティの値を取得する正しい方法は何ですか?

答えて

3

T::classKClass<T>ですが、t::classKClass<out T>となります。次のことを考えてみましょう:

class Foo { 
    val foo = 2 
    val bar = 3 
} 

fun f() { 
    val any: Any = Foo() 
    any::class.memberProperties.forEach { 
     println(it.get(2)) // Oops 
    } 
} 

これは、本質的に2.foo2.barにアクセスしようとしていましたが、それは代わりにタイプAnyのパラメータを可能にする注意の側にget ERRSので、許可されていません。ただし、t.javaClass.kotlinを実行するとKClass<T>が生成されます。上記のように誤解すると、IllegalArgumentExceptionが発生します。

あなたが KClassタイプと他には何のためになることをコンパイル時の保証を提供することにより、コンパイラにいくつかのより多くの助けを与えることができます

:それは指定することが可能かどう

private inline fun <reified A : Annotation, reified T : Any> foo(target: T) { 
    T::class.memberProperties 
      .filter { it.annotations.any { annotation -> annotation is A } } 
      .forEach { 
       println(it.get(target)) 
      } 
} 

は、残念ながら、私にはわかりません推測しながらATtargetから。私はそれをfoo<Attr, Bar>(bar)のように呼び出す方法を見つけていない。

private inline fun <reified A : Annotation> foo(target: Any) { 
    target.javaClass.kotlin.memberProperties 
      .filter { it.annotations.any { annotation -> annotation is A } } 
      .forEach { 
       println(it.get(target)) 
      } 
} 

我々は両方のケースで同じオブジェクトを渡すので、これは上記の問題に実行されません知っている:私はそれが少ないポータブルだ賭けると思いますけれども

また、あなたは、javaClassを通過することができます。これは呼び出し元の側でもうまく見えます。これは、移植性ヒットの価値があるかもしれません。

+0

代わりに 'target.javaClass.kotlin.memberProperties'を実行すると、' T'をまったく指定する必要はありません。 – Todd

+1

@トッド、面白い、なぜ彼らが異なるのだろうか。 – chris

関連する問題