Kotlin 获取非包扩展属性的KProperty

Kotlin 获取非包扩展属性的KProperty,kotlin,Kotlin,在kotlin中,可以使用“引用”操作符获取包扩展属性的KProperty,如下所示: val String.extProp: String get() = "Some get code" fun foo() { val prop: KProperty<String> = String::extProp } val String.extProp:String get()=“一些get代码” fun foo(){ val prop:KProperty=String:

在kotlin中,可以使用“引用”操作符获取包扩展属性的KProperty,如下所示:

val String.extProp: String
    get() = "Some get code"

fun foo() {
    val prop: KProperty<String> = String::extProp
}
val String.extProp:String
get()=“一些get代码”
fun foo(){
val prop:KProperty=String::extProp
}
但是,当在类内声明扩展属性时,引用运算符将不再工作:

class Example() {

    val String.extProp: String
        get() = "Some get code"

    fun foo() {
        val prop: KProperty<String> = String::extProp // error
    }

}
类示例(){
val String.extProp:String
get()=“一些get代码”
fun foo(){
val prop:KProperty=String::extProp//错误
}
}

因此,我想知道的是,如何更改第二个示例中有问题的行,从而获得KProperty?

您得到的错误是:

错误:(y,x)Kotlin:'extProp'同时是成员和扩展。不允许引用此类元素

没有语法机制来生成对扩展方法的引用,扩展方法也需要包含类。例如,您的扩展可能会使用该类的成员,这需要类似于Kotlin 1.1中的“”之类的内容(我也不确定它是否会涵盖这种情况,它目前是一个示例)。所以现在,没有可用的语法。像
Example::String::extProp
这样的东西不可用,常用的
Example::String.extProp
语法也不可用。但你可以通过思考找到它

首先,您需要知道您将收到的类型是:

KProperty2<INSTANCE, EXTENDING, PROPTYPE>
这对于检查来说有点过分了,但可以确保在以后添加任何其他类型的扩展时,它是未来的证明。以下是为使用它而更新的代码:

class Example() {
    val String.extProp: String
        get() = "howdy $this"

    fun foo() {
        val prop = Example::class.extProp(String::class, "extProp", String::class)
        println(prop.get(this, "stringy"))  // "howdy stringy"
    }
}
@Suppress("UNCHECKED_CAST")
fun <T: Any, EXTENDING: Any, R: Any> KClass<T>.extProp(extends: KClass<EXTENDING>, name: String, returning: KClass<R>): KProperty2<T, EXTENDING, R> {
    return this.declaredMemberExtensionProperties.first {
        it.name == name &&
                it.parameters.size == 2 &&
                it.parameters[0].kind == KParameter.Kind.INSTANCE && it.parameters[0].type == this.defaultType &&
                it.parameters[1].kind == KParameter.Kind.EXTENSION_RECEIVER && it.parameters[1].type == extends.defaultType &&
                it.returnType == returning.defaultType
    } as KProperty2<T, EXTENDING, R>
}
class Example() {
    val String.extProp: String
        get() = "howdy $this"

    fun foo() {
        val prop = Example::class.extProp(String::class, "extProp", String::class)
        println(prop.get(this, "stringy"))  // "howdy stringy"
    }
}