14-提供委托
9.3.6 提供委托
通过provideDelegate操作符,Kotlin允许扩展创建属性以及实现所委托对象的逻辑。通常,使用操作符provideDelegate将by右侧的对象定义为成员或扩展函数,调用该函数来创建属性的委托实例。
class ResourceLoader<T>(id: ResourceID<T>) {
operator fun provideDelegate(
thisRef: MyUI,
prop: KProperty<*>
): ReadOnlyProperty<MyUI, T> {
checkProperty(thisRef, prop.name)
// 创建委托
}
private fun checkProperty(thisRef: MyUI, name: String) { …… }
}
fun <T> bindResource(id: ResourceID<T>): ResourceLoader<T> { …… }
class MyUI {
val image by bindResource(ResourceID.image_id)
val text by bindResource(ResourceID.text_id)
}
使用provideDelegate操作符创建属性时(不仅仅在getter或setter 方法中使用),可以检查属性的一致性,provideDelegate的参数与getValue相同。
- thisRef:该参数必须与属性所有者类型相同或者是其超类型。
- prop:该参数必须是类型KProperty<*>或其超类型。
在上面的代码中,当创建MyUI实例时,系统会调用provideDelegate方法实现属性与委托之间的绑定关系并执行相关的校验操作。相对于属性声明编译生成的代码,使用provideDelegate生成的代码如下。
class C {
var prop: Type by MyDelegate()
}
//由编译器生成的provideDelegate代码
class C {
// 调用provideDelegate来创建额外的delegate属性
private val prop$delegate = MyDelegate().provideDelegate(this, this::prop)
val prop: Type
get() = prop$delegate.getValue(this, this::prop)
}
在生成的代码中,provideDelegate方法只会辅助属性的创建,并不会影响为getter或setter生成的代码。