dimanche 22 novembre 2020

Can I set a programmatically set a property of any type?

I'm trying to write a function that sets a property in a data class given a property type and a value. The data class has properties of several types, like String, View and Int, and some properties are nullable. I can make this work if I limit the functionality to one type, like this:

fun setDataValue(index: TableIndex, key: KMutableProperty1<CellData, String>, value: String) {
    val cellData = this.tableData[index]
    key.set(cellData, value)
}

setDataValue(0, CellData::name, "arlomedia")

But I can't find a way to allow multiple types, like this:

fun setDataValue(index: TableIndex, key: KMutableProperty1<CellData, Any?>, value: Any?) {
    val cellData = this.tableData[index]
    key.set(cellData, value)
}

setDataValue(0, CellData::name, "arlomedia")
setDataValue(0, CellData::status, null)
setDataValue(0, CellData::active, true)

In that case, the first function call shows the error, Type mismatch. Required: KMutableProperty1<CellData, Any?>, Found: KMutableProperty1<CellData, String>. I didn't expect that because Any? is a less specific type than String, so I figured I could supply a String when all that is required is Any?.

I also tried:

fun setDataValue(index: TableIndex, key: KMutableProperty1<CellData, *>, value: Any?) {
    val cellData = this.tableData[index]
    key.set(cellData, value)
}

setDataValue(0, CellData::name, "arlomedia")

In that case, the error on the function call goes away, but an error appears on the key.set line: Type mismatch. Required: Nothing, Found: Any?.

I suppose I could make a separate function for each data type and call the various functions as needed, but the purpose of this function is to abstract some more complex data access, and the benefit would be lost somewhat if I had to repeat that across multiple functions.

Is there a way to do this? I've been through the Kotlin Reflection documentation several times, plus this document (which for some reason I've only found in the "Migrating from Python" section), and many StackOverflow answers, but I haven't found anything that ties all the necessary pieces together.





Aucun commentaire:

Enregistrer un commentaire