Is it possible to instantiate a data class with dy...
# reflect
l
Is it possible to instantiate a data class with dynamic properties. Let's say I have this.
Copy code
data class Business(
    val id: Int,
    val name: String
)

val columns = listOf("id", "name")
val values = listOf(1, "Hello")
Is it possible to instantiate this class mapping dynamically my columns to contructor parameters?
e
Copy code
val cons = Business::class.primaryConstructor!!
val params = columns.map { name ->
    cons.parameters.single { it.name == name }
}
val business = cons.callBy(params.zip(values).toMap())
this does not check for multiple constructors, missing parameters, mismatched types, but may be enough to get you started
1
🙌 1
l
It totally works awesome thanks a lot.
d
If you can control the source for the data class you can achive this by property delegation: data class Business( private val _data : Map<String,Any> ) { val id : Int by _data val name : String by _data } val m = columns.zip( values ) { a,b -> a to b }.toMap()) val v = Business(m)
e
that's potentially unsafe, as
Copy code
Business(mapOf())
doesn't fail at construction time, but at some later point in time when the properties are accessed, and loses other features of data classes like copy
you could write
Copy code
data class Business(val id: Int, val name: String)
fun Business(data: Map<String, Any>): Business? {
    return Business(
        data["id"] as? Int ?: return null,
        data["name"] as? String ?: return null,
    )
}
if you want that interface without reflection
234 Views