kotlin - 如何使委托适用于类中的所有属性?
问题描述
我有一个类,A,需要在dirty
其属性之一发生更改时标记。
在查看了 Kotlin 文档之后,我知道我需要一个代表。到目前为止,我有:
abstract class CanBeDirty {
var isDirty = false
}
class A(
// properties getting set in constructor here
) : CanBeDirty {
var property1: String by DirtyDelegate()
var property2: Int by DirtyDelegate()
var property3: CustomObject by DirtyDelegate()
}
class DirtyDelegate() {
operator fun getValue(thisRef: CanBeDirty, property: KProperty<*>): Resource {
return valueOfTheProperty
}
operator fun setValue(thisRef: CanBeDirty, property: KProperty<*>, value: Any?) {
if (property != value) {
thisRef.isDirty = true
//set the value
}
else {
//don't set the value
}
}
}
我相信缺少设置与此有关,vetoable()
但我在 Kotlin 文档中看到的示例并没有真正向我展示如何使用完全形成的类 Delegate 来做到这一点(而且我只是不了解 Kotlin 语法,诚实地)。
解决方案
您的委托类需要自己的属性来存储它将返回的值。而且如果你不想处理未初始化的值,它还应该有一个构造函数参数作为初始值。您不必实现ReadWriteProperty
,但它允许 IDE 为两个运算符函数自动生成正确的签名。
class DirtyDelegate<T>(initialValue: T): ReadWriteProperty<CanBeDirty, T> {
private var _value = initialValue
override fun getValue(thisRef: CanBeDirty, property: KProperty<*>): T {
return _value
}
override fun setValue(thisRef: CanBeDirty, property: KProperty<*>, value: T) {
if (_value != value) {
_value = value
thisRef.isDirty = true
}
}
}
由于这需要一个初始值参数,因此您必须将其传递给构造函数:
class A: CanBeDirty() {
var property1: String by DirtyDelegate("")
var property2: Int by DirtyDelegate(0)
var property3: CustomObject by DirtyDelegate(CustomObject())
}
如果你想根据传递给构造函数的东西设置一个初始值,你可以这样做:
class B(initialName: String): CanBeDirty() {
var name by DirtyDelegate(initialName)
}
推荐阅读
- karabiner - 如何交换方括号和大括号(karabiner)
- c++ - 如何使用 C 指针的自定义删除器创建 unique_ptr?
- javascript - 将层次数组转换为平面数组
- python - 如何使用python更改xml文件的特定值
- vhdl - 无符号定点数(ufixed)和无符号数之间的VHDL算术运算
- perl - 将 SQL 查询的结果提取到 PERL 中的哈希映射中
- ssl - MAMP PRO - 为外部 POST 调用指定 .crt 和 .key 文件的路径
- python - 如何将值传播到熊猫系列的前 n 行
- java - 考虑在配置中定义“co.business.service.AppSessionService”类型的 bean
- c# - 无法写入 ExcelFile