Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delegate property to another property

Tags:

kotlin

Can you delegate a property to another property in Kotlin? I have the following code:

class SettingsPage {
  lateinit var tagCharacters: JTextField
  lateinit var tagForegroundColorChooser: ColorPanel
  lateinit var tagBackgroundColorChooser: ColorPanel

  var allowedChars: String
    get() = tagCharacters.text
    set(value) = tagCharacters.setText(value)

  var tagForegroundColor by tagForegroundColorChooser
  var tagBackgroundColor by tagBackgroundColorChooser
}

In order to get property delegation, I declare the following two extension functions:

  operator fun ColorPanel.getValue(a: SettingsPage, p: KProperty<*>) = selectedColor
  operator fun ColorPanel.setValue(a: SettingsPage, p: KProperty<*>, c: Color?) { selectedColor = c }

However, what I would like to write is something like the following:

class SettingsPage {
  lateinit var tagCharacters: JTextField
  lateinit var tagForegroundColorChooser: ColorPanel
  lateinit var tagBackgroundColorChooser: ColorPanel

  var allowedChars: String by Alias(tagCharacters.text)
  var tagForegroundColor by Alias(tagForegroundColorChooser.selectedColor)
  var tagBackgroundColor by Alias(tagBackgroundColorChooser.selectedColor)
}

Is this possible to do Kotlin? How do I write the class Alias?

like image 745
breandan Avatar asked Jul 13 '17 07:07

breandan


People also ask

What is a property delegate?

A “Delegate” is just a class that provides the value of a property and handles its changes. This will help us to delegate(assign or pass on), the getter-setter logic altogether to a different class so that it can help us in reusing the code. This is an alternative to inheritance property.

What is property delegation in Kotlin?

Delegation (in computer science) is the assignment of authority from one instance to another. It can operate mutable as well as static relationship between classes, and inheritance, in turn, is based on the constant concept.

What is Android delegation?

A delegate is just a class that provides the value for a property and handles its changes. This allows us to move, or delegate, the getter-setter logic from the property itself to a separate class, letting us reuse this logic.

What is Delegation pattern in Kotlin?

Android Dependency Injection using Dagger with Kotlin Kotlin supports “delegation” design pattern by introducing a new keyword “by”. Using this keyword or delegation methodology, Kotlin allows the derived class to access all the implemented public methods of an interface through a specific object.


1 Answers

UPD: Since Kotlin 1.4, the standard library includes the necessary extensions that allow this out of the box:

class MyClass(var memberInt: Int, val anotherClassInstance: ClassWithDelegate) {
    var delegatedToMember: Int by this::memberInt
    var delegatedToTopLevel: Int by ::topLevelInt
    
    val delegatedToAnotherClass: Int by anotherClassInstance::anotherClassInt
}
var MyClass.extDelegated: Int by ::topLevelInt

Yes, it's possible: you can use a bound callable reference for a property that you store in the alias, and then the Alias implementation will look like this:

class Alias<T>(val delegate: KMutableProperty0<T>) {
    operator fun getValue(thisRef: Any?, property: KProperty<*>): T = 
        delegate.get()

    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
        delegate.set(value) 
    }
}

And the usage:

class Container(var x: Int)

class Foo {
    var container = Container(1)
    var x by Alias(container::x)
}

To reference a property of the same instance, use this::someProperty.

like image 145
hotkey Avatar answered Oct 25 '22 03:10

hotkey