¿Cómo implementar una propiedad que proviene de una fuente determinada hasta que se establece directamente en Kotlin?

Actualmente tengo una propiedad declarada así:

class Foo(val base : FooBase){ var _number: Int? = null override var number: Int get() = _number ?: base.number set(value) {_number = value} } 

Sin embargo, tengo muchas properties como esta, que conducen a una gran cantidad de duplicación de código. Hay alguna manera de evitar esto? Entiendo que la delegación de properties es una forma de hacerlo, pero no estoy seguro de cómo implementar ReadWriteProperty<...> correctamente. ¿Cómo uso el valor de "propiedad", si se supone que debo usarlo?

Aquí hay una mejora en el performance sobre la respuesta de Yoav Sternberg. Como puede ver, es less genérico, pero evita el auto-boxing para ints:

 class IntUninitializedProperty(private val getter: () -> Int) { private var isInitialised = false private var value: Int = 0 fun getValue(thisRef: Any?, property: KProperty<*>): Int = if(isInitialised) value else getter() fun setValue(thisRef: Any?, property: KProperty<*>, value: Int) { this.value = value isInitialised = true } } 

Debe crear una class que amplíe ReadWriteProperty que proporciona la funcionalidad (el ejemplo del código se basa en la implementación diferida insegura)

 class UninitializedProperty<T>(private val getter: () -> T) : ReadWriteProperty<Any?, T> { var _value: Any? = UNINITIALIZED_VALUE @Suppress("UNCHECKED_CAST") override fun getValue(thisRef: Any?, property: KProperty<*>): T = if(_value === UNINITIALIZED_VALUE) getter() else _value as T override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) { _value = value } private object UNINITIALIZED_VALUE } 

A continuación, defina un método de ayuda para mantener la constancia con los delegates de normas como lazy :

 fun <T> uninitialized(getter: () -> T): ReadWriteProperty<Any?, T> = UninitializedProperty(getter) 

Ahora puedes usarlo:

 class Foo(val base: FooBase) { override var number: Int by uninitialized { base.number } } 

Nota: La class no es segura para subprocesss.

Consulte la documentation oficial para get más información sobre la delegación.

  • Kotlin: cómo acceder a las properties en el constructor
  • ¿Hay un análogo didSet / willSet en Kotlin?
  • En TornadoFX, ¿cómo puedo vincular las properties de BigDecimal a otra propiedad de BigDecimal usando objectBinding?
  • No se puede usar getter personalizado con propiedad delegada
  • Al crear una interfaz en Kotlin, ¿importa si las properties tienen get / set?
  • Propiedad protegida abstracta Kotlin
  • Kotlin - Inicialización de propiedad usando "por perezoso" vs. "tardío"
  • ¿Cuál es la forma más sencilla de get propiedad segura para subprocesss en Kotlin?
  • En TornadoFX, ¿cómo puedo hacer que una propiedad cambie cuando cambian otras properties?
  • Función de extensión Kotlin en propiedad mutable
  • Obtención de información de KProperty dentro de la propiedad delegada fuera de las funciones getValue () y setValue ()