获取非包扩展属性的KProperty

kotlin中,可以使用引用运算符来获取包扩展属性的KProperty,如下所示:

val String.extProp: String get() = "Some get code" fun foo() { val prop: KProperty<String> = String::extProp } 

但是,扩展属性在类中声明时,引用操作符不再有效:

 class Example() { val String.extProp: String get() = "Some get code" fun foo() { val prop: KProperty<String> = String::extProp // error } } 

所以我想知道的是如何在第二个示例中更改有问题的行,因此KProperty被获取?

One Solution collect form web for “获取非包扩展属性的KProperty”

你得到的错误是:

错误:(y,x)Kotlin:'extProp'同时是一个成员和一个扩展。 对这些元素的引用是不允许的

没有语法机制来生成也需要包含类的扩展方法的引用。 例如,你的扩展可能会使用类的成员,这将需要类似Kotlin 1.1中的“ 绑定引用 ”(我不确定会覆盖这种情况,目前是一个未解决的问题 )。 所以现在, 没有::语法可用。 像Example::String::extProp不可用的,也不是常用的Example::String.extProp语法。 但你可以通过反思找到它。

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

 KProperty2<INSTANCE, EXTENDING, PROPTYPE> 

而一个类的正常属性是:

 KProperty1<INSTANCE, PROPTYPE> 

您需要知道,因为任何对getter调用都需要类实例和属性正在扩展的类实例。 所以你不能像调用一个类的属性引用那样调用它。

您可以使用此函数来查找在类中声明的扩展属性:

 @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" } } 
  • 如何使用RxJava2 combineLatest与Kotlin中的可观察列表
  • Kotlin:Dagger2 @Inject context var始终为空
  • Android室 - 简单的选择查询 - 无法访问主线程上的数据库
  • 如何避免空检查
  • Java Stream with :: new to Kotlin
  • 如何在kotlin中的when语句中添加多个语句
  • 没有IDE协助的Kotlin为Gradle设置 - Kotlin类没有使它成为classpath
  • Hibernate OneToMany从父节点绑定错误
  • 在平台/语言之间共享代码(例如Swift,Kotlin,JavaScript)
  • Android将kotlin资源部署到maven资源库
  • 使用Mockito和InjectMocks时Kotlin懒惰块不执行
  • Kotlin language will be the best programming language for Android.