Home > Software engineering >  Kotlin: can I get an object inside an object using variable whose value is the name of an object?
Kotlin: can I get an object inside an object using variable whose value is the name of an object?

Time:01-21

The title is probably confusing, but I didn't know how to explain it better. Usually I use javascript, and in it you can have this:

var objectVar = "myOtherVariable";

var someObject = {
    myVariable: "something",
    myOtherVariable: "something else"
}

// writes out 'something else'
console.log(someObject[objectVar])

Is it possible to do something like this in kotlin?

For instance, if you have

val myVar = "a"
object someObject{
    var a: MutableSet<ImageView> = mutableSetOf()
    var b: MutableSet<ImageView> = mutableSetOf()
}

can you, in any way, get to the someObject.a by using myVar?

Thank you

CodePudding user response:

import kotlin.reflect.full.declaredMembers

inline fun <reified T: Any> getPropertyByName(instance: T, name: String): Any? {
  return instance::class.declaredMembers.firstOrNull { it.name == name }?.call(instance)
}

// Test:

object SomeObject {
  var a: MutableSet<Int> = mutableSetOf(1, 2, 3)
  var b: MutableSet<Int> = mutableSetOf(9, 8, 7)
}

println(getPropertyByName(SomeObject, "a"))   // Output: [1, 2, 3]
println(getPropertyByName(SomeObject, "b"))   // Output: [9, 8, 7]

@Suppress("UNCHECKED_CAST")
val mySet: MutableSet<Int> = getPropertyByName(SomeObject, "a") as MutableSet<Int>
mySet.add(4)
println(mySet)   // Output: [1, 2, 3, 4]

CodePudding user response:

Might not be directly applicable to your use case, but here are some idiomatic alternatives that do not require dark magic:

class MyObject {
    var a: MutableSet<String> = mutableSetOf("foo")
    var b: MutableSet<String> = mutableSetOf("bar")
}

val obj = MyObject()

// Get via property reference
val property = MyObject::a
println(property.get(obj))

// Get via lambda that returns the property value
val accessor : MyObject.() -> MutableSet<String> = { a }
println(obj.accessor())

In either case, instead of passing around a String holding the name of the property, you'd pass around a piece of code that accesses the property.

  • Related