There is one design decision with delegate properties I never understood.
The answer to this question by @kyay10 provided the solution, so now this post is being becomes a post for anyone else who has the same questions, rather than remaining as a question.
Why was this format (From the documentation):
class Example {
var p: String by Delegate()
}
import kotlin.reflect.KProperty
class Delegate {
operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
return "$thisRef, thank you for delegating '${property.name}' to me!"
}
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
println("$value has been assigned to '${property.name}' in $thisRef.")
}
}
chosen and not this format?
import kotlin.reflect.KProperty
class Delegate(val thisRef: Any?, val property: KProperty<*>) {
operator fun getValue(): String {
return "$thisRef, thank you for delegating '${property.name}' to me!"
}
operator fun setValue(value: String) {
println("$value has been assigned to '${property.name}' in $thisRef.")
}
}
Using this approach from other languages can be difficult to convert, as a table of delegate objects is required. If the table of delegate objects should contain the property names, and this becomes messy with the above syntax. That syntax does allow for the same instance of the Delegate class to be reused for multiple properties, but does not provide the delegate object itself with access to the parent object or the KProperty object.
I made a language design request to allow an alternate syntax supporting the Delegate constructor receiving the thisRef
and property
parameters.
In fact, as answered below, this already exists by way of the provideDelegate
function.