Given an interface:
interface Countable
{
val count: Int
}
And an implementation/factory:
fun countable(counter: () -> Int): Countable = object : Countable
{
override val count: Int
get() = counter()
}
I can implement this using the class by
delegation feature:
class CountableThing : Countable by countable({ 123 })
So that this snippet predictably outputs 123
:
fun main()
{
val countableThing = CountableThing()
println(countableThing.count)
}
My question is, in the context of the delegate class, is there any way to get an instance of the delegating receiver?
In other words, can my delegate Countable
implementation (the anonymous object defined in fun countable
) see/access the receiver instance of the CountableThing
class?
I tried this:
fun <T> countable(receiver: T, counter: () -> Int): Countable = object : Countable
{
// ...
}
class CountableThing : Countable by countable<CountableThing>(this, { 123 })
But that's not valid, because expectedly:
class CountableThing : Countable by countable<CountableThing>(this, { 123 })
/^^^^
'this' is not defined in this context
No it can't, delegate objects are just objects they don't even know if they're going to be used to implement an interface through delegation. However, you can consider using delegated properties which are used to delegate properties setters and getters implementations:
class Example {
var p: String by Delegate()
}
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.")
}
}
then you can use
val e = Example()
println(e.p)
which prints:
Example@33a17727, thank you for delegating ‘p’ to me!
As you can see, in your delegate implementation you can use thisRef
which is a reference to the object whose property is been delegated.