¿Cómo puedo get el nombre de una propiedad de Kotlin?

Tengo la siguiente function para acceder al delegado de una propiedad. Utiliza el reflection de Kotlin para get el nombre de una propiedad y la reflexión de Java para get el campo.

fun Any.getDelegate<T>(prop: KProperty<T>): Any { return javaClass.getDeclanetworkingField("${prop.name}\$delegate").let { it.setAccessible(true) it.get(this) } } 

El método se usa así:

 val delegate = a.getDelegate(A::b) 

Sin embargo, preferiría usarlo así:

 val delegate = abdelegate 

El problema con el código anterior es get el nombre de la propiedad de ab y get la instancia a de ab . Por lo que sé sobre Kotlin, probablemente esto no sea posible; sin embargo, me gustaría ver si puedo limpiar mi function.

Para dar una idea más amplia de lo que estoy intentando hacer, aquí está mi código completo. Quiero un delegado observable al que pueda agregar y eliminar observadores utilizando la reference de delegado y sin crear variables de sum.

 fun Any.addObservable<T>(prop: KProperty<T>, observer: (T) -> Unit) { getObservableProperty(prop).observers.add(observer) } fun Any.getObservableProperty<T>(prop: KProperty<T>): ObservableProperty<T> { return getDelegate(prop) as ObservableProperty<T> } fun Any.getDelegate<T>(prop: KProperty<T>): Any { return javaClass.getDeclanetworkingField("${prop.name}\$delegate").let { it.setAccessible(true) it.get(this) } } class ObservableProperty<T>( initialValue: T, initialObservers: Array<(T) -> Unit> = emptyArray()) : ReadWriteProperty<Any?, T> { private var value = initialValue public val observers: MutableSet<(T) -> Unit> = initialObservers.toHashSet() public override fun get(thisRef: Any?, desc: PropertyMetadata): T { return value } public override fun set(thisRef: Any?, desc: PropertyMetadata, value: T) { this.value = value observers.forEach { it(value) } } } class A() { var b by ObservableProperty(0) } fun main(args: Array<String>) { val a = A() a.addObservable(A::b) { println("b is now $it") } ab = 1 ab = 2 ab = 3 } 

Editar :

Me acabo de dar count de que la function tampoco es estricta porque el nombre del campo del delegado de la propiedad está referencedo por el nombre de KProperty , que no requiere una reference fuerte a la class adjunta. Aquí hay un ejemplo para demostrar el problema:

 class A() { var foo by ObservableProperty(0) } class B() { var foo by ObservableProperty(0) } fun main(args: Array<String>) { val a = A() a.addObservable(B::foo) { println("b is now $it") } a.foo = 1 a.foo = 2 a.foo = 3 } 

Esto se comstack y se ejecuta sin error porque A::foo y B::foo dan como resultado una cadena de campo de "foo$delegate .

En este momento, la reflexión es todo lo que podemos hacer para llegar al object delegado. Estamos diseñando una function de idioma para tener acceso directo a la instancia de delegado, pero es un largo path por recorrer.

Así es como se obtiene el nombre de una propiedad de Kotlin (aunque solo con una instancia de la class). Esta parte será útil para cualquiera que llegue a esta pregunta basándose exclusivamente en su título.

 class Stuff(val thing: String) val stuff = Stuff("cool stuff") val thingFieldName = "${stuff.thing}\$delegate" // value of thingFieldName is now "thing" 

En términos de conseguir que el delegado sea más fácil, dicen que ahora puede hacer esto:

 class Foo { var bar: String by ReactiveProperty<String>() } val foo = Foo() val bar = foo.bar val barDelegate = ... // foo.bar$delegate 

Ver boleto.

  • El operador de Kotlin Reflection obtiene la implementación
  • Kotlin language obtiene class en time de ejecución
  • ¿Cómo uso el object Kotlin por reflexión?
  • Determinar si una instancia es una instancia de una class de datos
  • Kotlin: comparar los valores de propiedad de diferentes objects objective con (fuera) reflexión
  • ¿Cómo establecer el valor de propiedad delegada por reflexión en kotlin?
  • ¿Cómo puedo get una reference a un object Kotlin por su nombre?
  • ¿Cómo get la reference de class de KParameter en kotlin?
  • Kotlin obtiene la anotación de campo siempre vacía
  • Kotlin comtesting si la function requiere parámetro de instancia
  • Kotlin: ¿Es aquí una forma inteligente de lanzar NotImplementedError para todos los methods de una class?