¿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 hacer una propiedad delegada por map con un nombre personalizado?
  • ¿Cuál es la forma más sencilla de get propiedad segura para subprocesss en Kotlin?
  • En TornadoFX, ¿cómo puedo vincular las properties de BigDecimal a otra propiedad de BigDecimal usando objectBinding?
  • Kotlin: ¿Cómo puedo evitar el autoboxing (basura) en las properties delegadas?
  • Property setter con diferente tipo
  • Kotlin: cómo acceder a las properties en el constructor
  • Convierta variables estáticas de Java a Kotlin
  • Kotlin getter setter sin campo
  • En TornadoFX, ¿cómo puedo hacer que una propiedad cambie cuando cambian otras properties?
  • Función de extensión Kotlin en propiedad mutable
  • Al crear una interfaz en Kotlin, ¿importa si las properties tienen get / set?