Делегация этого не поддерживает. Делегат должен быть создан до класса, который ему делегирует, поэтому делегат не может полагаться на него для построения. Еще одна проблема заключается в том, что, хотя вы можете переопределить функции делегата, если делегат внутренне вызывает эти функции, он вызывает исходную версию, а не переопределение. Делегат действительно живет в своем собственном мире.
Но вы можете настроить его, чтобы хост передавал себя делегату в его блоке инициализации:
interface Foo<T> {
var host: T
fun doSomething()
}
class FooImpl : Foo<Bar> {
override lateinit var host: Bar
override fun doSomething() {
println(host.name)
}
}
class Bar(val name: String): Foo<Bar> by FooImpl() {
init {
host = this
}
}
fun main() {
val bar = Bar("Hello world")
bar.doSomething()
}
Это, к сожалению, приведет к открытию хоста к возможности отключения от собственного делегата внешними классами. Возможно, вы могли бы заставить свойство генерировать исключение, если оно назначено более одного раза.
Вот делегат свойства, который может это сделать:
private class SingleAssignmentVar<T>: ReadWriteProperty<Any, T> {
private var value: T? = null
private var assigned: Boolean = false
@Suppress("UNCHECKED_CAST")
override fun getValue(thisRef: Any, property: KProperty<*>): T {
if (!assigned)
error("Property has not yet been set.")
return value as T
}
override fun setValue(thisRef: Any, property: KProperty<*>, value: T) {
if (assigned)
error("Property may only be set once.")
assigned = true
this.value = value
}
}
fun <T> Delegates.singleAssignment(): ReadWriteProperty<Any, T> = SingleAssignmentVar()