Reflection 如何获取Kotlin酒店的名称?

Reflection 如何获取Kotlin酒店的名称?,reflection,delegation,kotlin,Reflection,Delegation,Kotlin,我有以下函数来访问属性的委托。它使用Kotlin反射获取属性名称,使用Java反射获取字段 fun Any.getDelegate<T>(prop: KProperty<T>): Any { return javaClass.getDeclaredField("${prop.name}\$delegate").let { it.setAccessible(true) it.get(this) } } 但是,我更愿意这样使用

我有以下函数来访问属性的委托。它使用Kotlin反射获取属性名称,使用Java反射获取字段

fun Any.getDelegate<T>(prop: KProperty<T>): Any {
    return javaClass.getDeclaredField("${prop.name}\$delegate").let {
        it.setAccessible(true)
        it.get(this)
    }
}
但是,我更愿意这样使用它:

val delegate = a.getDelegate(A::b)
val delegate = a.b.delegate
上面代码的问题是获取
a.b
的属性名,以及从
a.b
获取实例
a
。从我对Kotlin的了解来看,这可能是不可能的,但是我想看看是否可以清理我的函数

为了更全面地了解我正在尝试做什么,这里是我的完整代码。我想要一个可观察的委托,我可以使用委托引用向其添加和删除观察者,而无需创建附加变量

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.getDeclaredField("${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")
    }

    a.b = 1
    a.b = 2
    a.b = 3
}

由于
A::foo
B::foo
都会导致字段字符串
“foo$delegate

现在,我们所能做的就是通过反射来访问delegate对象。我们正在设计一种语言特性来直接访问委托实例,但这还有很长的路要走

这是获取Kotlin属性名称的方式(尽管仅使用类的实例)。这一部分对于纯粹根据题目来回答这个问题的人来说是有用的

class Stuff(val thing: String)

val stuff = Stuff("cool stuff")
val thingFieldName = "${stuff.thing}\$delegate"
// value of thingFieldName is now "thing"
为了使代理本身更容易,他们说您现在可以这样做:

class Foo {
    var bar: String by ReactiveProperty<String>()
}

val foo = Foo()
val bar = foo.bar
val barDelegate = ... // foo.bar$delegate
class-Foo{
变量栏:由ReactiveProperty()生成的字符串
}
val foo=foo()
val bar=foo.bar
val barDelegate=…//foo.bar$delegate

这很有趣。是否有需要遵循的问题或需要阅读的规范?不,不幸的是,没有任何地方。现在,这是一些讨论日志,就这样:)很高兴知道您正在处理委托访问,我已经尽了最大努力。谢谢。@Ilyzhenkov这方面有什么进展吗?@daka reflection改进为可以直接访问代表,请参阅
class Foo {
    var bar: String by ReactiveProperty<String>()
}

val foo = Foo()
val bar = foo.bar
val barDelegate = ... // foo.bar$delegate