# Delegation to instance fields/whatever

**URL:** <https://discuss.kotlinlang.org/t/delegation-to-instance-fields-whatever/13862>\
**Category:** Language Design\
**Created:** [August 14, 2019, 10:33am UTC](https://discuss.kotlinlang.org/t/delegation-to-instance-fields-whatever/13862 "2019-08-14T10:33:55Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![LoganDark](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/logandark/32/6651_2.png) [@LoganDark](https://discuss.kotlinlang.org/u/LoganDark)\
**Post date:** [August 14, 2019, 10:33am UTC](https://discuss.kotlinlang.org/t/delegation-to-instance-fields-whatever/13862/1 "2019-08-14T10:33:55Z")

</div>

```auto
class PorterConfiguration(val file: File) : Configuration by config {
	lateinit var config: FileConfiguration private set

```

…Oh, wait. Nope. Kotlin didn’t like that. Let’s try again…

```auto
class PorterConfiguration(val file: File) : Configuration {
	lateinit var config: FileConfiguration private set

	//<editor-fold desc="...since Kotlin won't let me use "Configuration by config"...">
	// @formatter:off
	@Suppress("KDocMissingDocumentation")
	override fun isSet(path: String?): Boolean = config.isSet(path)
	@Suppress("KDocMissingDocumentation")
	override fun isVector(path: String?): Boolean = config.isVector(path)
	@Suppress("KDocMissingDocumentation")
	override fun getFloatList(path: String?): MutableList<Float> = config.getFloatList(path)
	@Suppress("KDocMissingDocumentation")
	override fun getVector(path: String?): Vector = config.getVector(path)
	@Suppress("KDocMissingDocumentation")
	override fun getVector(path: String?, def: Vector?): Vector = config.getVector(path, def)
	@Suppress("KDocMissingDocumentation")
	override fun getLong(path: String?): Long = config.getLong(path)
	@Suppress("KDocMissingDocumentation")
	override fun getLong(path: String?, def: Long): Long = config.getLong(path, def)
	@Suppress("KDocMissingDocumentation")
	override fun getItemStack(path: String?): ItemStack = config.getItemStack(path)
	@Suppress("KDocMissingDocumentation")
	override fun getItemStack(path: String?, def: ItemStack?): ItemStack = config.getItemStack(path, def)
	@Suppress("KDocMissingDocumentation")
	override fun isList(path: String?): Boolean = config.isList(path)
	@Suppress("KDocMissingDocumentation", "UsePropertyAccessSyntax")
	override fun setDefaults(defaults: Configuration?) = config.setDefaults(defaults)
	@Suppress("KDocMissingDocumentation", "UsePropertyAccessSyntax")
	override fun getDefaultSection(): ConfigurationSection = config.getDefaultSection()
	@Suppress("KDocMissingDocumentation")
	override fun isInt(path: String?): Boolean = config.isInt(path)
	@Suppress("KDocMissingDocumentation")
	override fun getBoolean(path: String?): Boolean = config.getBoolean(path)
	@Suppress("KDocMissingDocumentation")
	override fun getBoolean(path: String?, def: Boolean): Boolean = config.getBoolean(path, def)
	@Suppress("KDocMissingDocumentation")
	override fun getColor(path: String?): Color = config.getColor(path)
	@Suppress("KDocMissingDocumentation")
	override fun getColor(path: String?, def: Color?): Color = config.getColor(path, def)
	@Suppress("KDocMissingDocumentation")
	override fun isItemStack(path: String?): Boolean = config.isItemStack(path)
	@Suppress("KDocMissingDocumentation")
	override fun createSection(path: String?): ConfigurationSection = config.createSection(path)
	@Suppress("KDocMissingDocumentation")
	override fun createSection(path: String?, map: MutableMap<*, *>?): ConfigurationSection = config.createSection(path, map)
	@Suppress("KDocMissingDocumentation")
	override fun isDouble(path: String?): Boolean = config.isDouble(path)
	@Suppress("KDocMissingDocumentation")
	override fun getBooleanList(path: String?): MutableList<Boolean> = config.getBooleanList(path)
	@Suppress("KDocMissingDocumentation")
	override fun isColor(path: String?): Boolean = config.isColor(path)
	@Suppress("KDocMissingDocumentation")
	override fun getList(path: String?): MutableList<*> = config.getList(path)
	@Suppress("KDocMissingDocumentation")
	override fun getList(path: String?, def: MutableList<*>?): MutableList<*> = config.getList(path, def)
	@Suppress("KDocMissingDocumentation")
	override fun getLongList(path: String?): MutableList<Long> = config.getLongList(path)
	@Suppress("KDocMissingDocumentation")
	override fun isConfigurationSection(path: String?): Boolean = config.isConfigurationSection(path)
	@Suppress("KDocMissingDocumentation", "UsePropertyAccessSyntax")
	override fun getRoot(): Configuration = config.getRoot()
	@Suppress("KDocMissingDocumentation")
	override fun getOfflinePlayer(path: String?): OfflinePlayer = config.getOfflinePlayer(path)
	@Suppress("KDocMissingDocumentation")
	override fun getOfflinePlayer(path: String?, def: OfflinePlayer?): OfflinePlayer = config.getOfflinePlayer(path, def)
	@Suppress("KDocMissingDocumentation")
	override fun getCharacterList(path: String?): MutableList<Char> = config.getCharacterList(path)
	@Suppress("KDocMissingDocumentation")
	override fun contains(path: String?): Boolean = config.contains(path)
	@Suppress("KDocMissingDocumentation")
	override fun contains(path: String?, ignoreDefault: Boolean): Boolean = config.contains(path, ignoreDefault)
	@Suppress("KDocMissingDocumentation")
	override fun isString(path: String?): Boolean = config.isString(path)
	@Suppress("KDocMissingDocumentation")
	override fun getDoubleList(path: String?): MutableList<Double> = config.getDoubleList(path)
	@Suppress("KDocMissingDocumentation", "UsePropertyAccessSyntax")
	override fun getName(): String = config.getName()
	@Suppress("KDocMissingDocumentation")
	override fun getIntegerList(path: String?): MutableList<Int> = config.getIntegerList(path)
	@Suppress("KDocMissingDocumentation")
	override fun getConfigurationSection(path: String?): ConfigurationSection = config.getConfigurationSection(path)
	@Suppress("KDocMissingDocumentation")
	override fun get(path: String?): Any = config.get(path)
	@Suppress("KDocMissingDocumentation")
	override fun get(path: String?, def: Any?): Any = config.get(path, def)
	@Suppress("KDocMissingDocumentation", "UsePropertyAccessSyntax")
	override fun getCurrentPath(): String = config.getCurrentPath()
	@Suppress("KDocMissingDocumentation")
	override fun getDouble(path: String?): Double = config.getDouble(path)
	@Suppress("KDocMissingDocumentation")
	override fun getDouble(path: String?, def: Double): Double = config.getDouble(path, def)
	@Suppress("KDocMissingDocumentation", "UsePropertyAccessSyntax")
	override fun getDefaults(): Configuration = config.getDefaults()
	@Suppress("KDocMissingDocumentation")
	override fun getByteList(path: String?): MutableList<Byte> = config.getByteList(path)
	@Suppress("KDocMissingDocumentation")
	override fun isOfflinePlayer(path: String?): Boolean = config.isOfflinePlayer(path)
	@Suppress("KDocMissingDocumentation", "UsePropertyAccessSyntax")
	override fun getParent(): ConfigurationSection = config.getParent()
	@Suppress("KDocMissingDocumentation")
	override fun getStringList(path: String?): MutableList<String> = config.getStringList(path)
	@Suppress("KDocMissingDocumentation")
	override fun getKeys(deep: Boolean): MutableSet<String> = config.getKeys(deep)
	@Suppress("KDocMissingDocumentation")
	override fun getInt(path: String?): Int = config.getInt(path)
	@Suppress("KDocMissingDocumentation")
	override fun getInt(path: String?, def: Int): Int = config.getInt(path, def)
	@Suppress("KDocMissingDocumentation")
	override fun options(): ConfigurationOptions = config.options()
	@Suppress("KDocMissingDocumentation")
	override fun getMapList(path: String?): MutableList<MutableMap<*, *>> = config.getMapList(path)
	@Suppress("KDocMissingDocumentation")
	override fun set(path: String?, value: Any?) = config.set(path, value)
	@Suppress("KDocMissingDocumentation")
	override fun isBoolean(path: String?): Boolean = config.isBoolean(path)
	@Suppress("KDocMissingDocumentation")
	override fun addDefaults(defaults: MutableMap<String, Any>?) = config.addDefaults(defaults)
	@Suppress("KDocMissingDocumentation")
	override fun addDefaults(defaults: Configuration?) = config.addDefaults(defaults)
	@Suppress("KDocMissingDocumentation")
	override fun getValues(deep: Boolean): MutableMap<String, Any> = config.getValues(deep)
	@Suppress("KDocMissingDocumentation")
	override fun <T : ConfigurationSerializable?> getSerializable(path: String?, clazz: Class<T>?): T = config.getSerializable(path, clazz)
	@Suppress("KDocMissingDocumentation")
	override fun <T : ConfigurationSerializable?> getSerializable(path: String?, clazz: Class<T>?, def: T): T = config.getSerializable(path, clazz, def)
	@Suppress("KDocMissingDocumentation")
	override fun isLong(path: String?): Boolean = config.isLong(path)
	@Suppress("KDocMissingDocumentation")
	override fun addDefault(path: String?, value: Any?) = config.addDefault(path, value)
	@Suppress("KDocMissingDocumentation")
	override fun getString(path: String?): String = config.getString(path)
	@Suppress("KDocMissingDocumentation")
	override fun getString(path: String?, def: String?): String = config.getString(path, def)
	@Suppress("KDocMissingDocumentation")
	override fun getShortList(path: String?): MutableList<Short> = config.getShortList(path)
	// @formatter:on
	//</editor-fold>

```

Dumb Kotlin. This was totally worth the time I put into it due to the lack of `by config` support.

Since methods are generated _inside the class_, why can’t I delegate to variables/fields _also declared inside the class_?

I tried to use the search here, but I didn’t know what to look for, so if this has been posted before then please let me know.

It looks like delegation would be perfect here, but Kotlin for some god-forsaken reason thinks I don’t deserve the auto-generated methods, so it forces me to implement around 100 methods like THAT. (I haven’t double-checked, but it looks like around 100? It’s still a lot.)

Is there any way to get around this, other than shoving that variable into the constructor?

---

<div class="post-metadata">

**Author:** ![al3c](https://avatars.discourse-cdn.com/v4/letter/a/e47774/32.png) [@al3c](https://discuss.kotlinlang.org/u/al3c)\
**Post date:** [August 14, 2019, 1:54pm UTC](https://discuss.kotlinlang.org/t/delegation-to-instance-fields-whatever/13862/2 "2019-08-14T13:54:45Z")

</div>

With `lateinit` there are some issues, what would happen if a delegated to method is called before the lateinit variable is set?  
There might also be some unexpected behavior if the delegated to object changes during the lifetime of `PorterConfiguration`.

For your use case I’d suggest to just expose the inner `config` object.

Otherwise you can try to refactor your code so that `PorterConfiguration` gets created after config is.

---

<div class="post-metadata">

**Author:** ![LoganDark](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/logandark/32/6651_2.png) [@LoganDark](https://discuss.kotlinlang.org/u/LoganDark)\
**Post date:** [August 14, 2019, 10:16pm UTC](https://discuss.kotlinlang.org/t/delegation-to-instance-fields-whatever/13862/3 "2019-08-14T22:16:23Z")

</div>

> [@al3c](#):
>
> what would happen if a delegated to method is called before the lateinit variable is set?

Then it would throw an exception, like any other lateinit variable.

> [@al3c](#):
>
> For your use case I’d suggest to just expose the inner `config` object.

Yeah, `private set` seems more appropriate for this than delegation.

I still think this should be a feature though.

---

<div class="post-metadata">

**Author:** ![Prototik](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/prototik/32/6489_2.png) [@Prototik](https://discuss.kotlinlang.org/u/Prototik)\
**Post date:** [August 27, 2019, 5:39am UTC](https://discuss.kotlinlang.org/t/delegation-to-instance-fields-whatever/13862/4 "2019-08-27T05:39:47Z")

</div>

Probably secondary constructor enough here?  
Something like this:

```kotlin
class PorterConfiguration(config: Configuration) : Configuration by config {
  constructor(file: File) : this(FileConfiguration(file))

```

Not sure about lateinit though but maybe a way to make lateinit var of PorterConfiguration itself.
