kotlin delegate property ,In a get() method how i can access the value?
Asked Answered
A

1

6

Kotlin has delegated properties which is a very nice feature. But I am figuring out how to get and set the values. Let's say I want to get value of the property which is delegated. In a get() method how i can access the value?

Here's an example of how I have implemented:

class Example() {
    var p: String by DelegateExample()
}
class DelegateExample {
    operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
        return "${property.name} "
    }

  operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
    println("${value.trim()} '${property.name.toUpperCase()} '")
   }
}
fun delegate(): String {
    val e = Example()
    e.p = "NEW"
    return e.p
}

The main question I am unable to understand is, How can I set the value to the actual property on which the delegation class is assigned. When I assign "NEW" to property p, how can I store that value to the variable p or read that new value passed on to p with get? Am I missing something basic here? Any help will be much appreciated. Thanks in advance.

Amparoampelopsis answered 4/12, 2017 at 13:31 Comment(1)
Get and set operations on p are delegated to the instance of your DelegateExample, so there is no real p of type String. Just use a variable in DelegateExample to hold the value.Mohun
E
11

Just create property in delegate which will hold the value

class DelegateExample {

    private var value: String? = null        

    operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
        return value ?: throw IllegalStateException("Initalize me!")
    }

    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
        this.value = value
    }
}

To clarify - delegates aren't values holder, they are handlers of get/set operations. You can take a look how it works under the hood if you decompile your Example class (Tools -> Kotlin -> Show Kotlin bytecode -> Decompile).

public final class Example {
   // $FF: synthetic field
   static final KProperty[] $$delegatedProperties = ...

   @NotNull
   private final DelegateExample p$delegate = new DelegateExample();

   @NotNull
   public final String getP() {
       return (String)this.p$delegate.getValue(this, $$delegatedProperties[0]);
   }

   public final void setP(@NotNull String var1) {
       Intrinsics.checkParameterIsNotNull(var1, "<set-?>");
       this.p$delegate.setValue(this, $$delegatedProperties[0], var1);
   }
}

No magic here, just creating instance of the DelegateExample and its get/set method invoking

Eudosia answered 4/12, 2017 at 13:35 Comment(2)
Great! Thanks for de-compiled class example!Dalury
Really such a great example!Amparoampelopsis

© 2022 - 2024 — McMap. All rights reserved.