¿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.

  • ¿Cómo obtengo las funciones declaradas de una class Kotlin (KClass en M12)?
  • ¿Cómo get una class de time de ejecución de una variable en Kotlin?
  • ¿Cómo puedo get una reference a un object Kotlin por su nombre?
  • Kotlin comtesting si la function requiere parámetro de instancia
  • Kotlin: comparar los valores de propiedad de diferentes objects objective con (fuera) reflexión
  • ¿Cómo puedo establecer una propiedad de un object complementario en Kotlin a través de la reflexión?
  • Quiero detectar si una class JVM es una class Kotlin o no
  • Reflexión de Kotlin: compruebe si la propiedad tiene tipo
  • Crear una nueva instancia de una KClass
  • ¿Cómo establecer el valor de propiedad delegada por reflexión en kotlin?
  • Kotlin, cómo recuperar el valor del campo a través de la reflexión