3
votes

Classe de données Kotlin - accédez à la propriété par variable pour définir sa valeur

J'ai une classe de données Kotlin comme celle-ci:

prop.set(user, "Alex")

Puis je crée son instance

prop.setter.call(user, "Alex")

Alors j'essaye ceci:

val field = "name"
var prop = User::class.memberProperties.find {it -> it.name == field}!!
prop.get(user)

Et cela fonctionne, mais si j'essaie de définir une valeur comme celle-ci:

var user = User(1)

J'obtiens une erreur:

Référence non résolue: setter

Cela ne fonctionne pas non plus comme ça:

data class User(
    var id: Int,
    var name: String? = null,
    var email: String? = null,
    var age: Int? = null,
    var latitude: Float? = null,
    var longitude: Float? = null 
)

(Ceci était basé sur la solution fournie ici, mais cela ne fonctionne pas pour moi: solution )


0 commentaires

3 Réponses :


1
votes

memberProperties renvoie une Collection<KProperty1<T, *>> , mais vous avez besoin de KMutableProperty1 . Donc

if (prop is KMutableProperty1) {
    (prop as KMutableProperty1<T, Any>).set(user, "Alex")
} else { 
    // what do you want to do if the property is immutable?
}

Le cast est nécessaire car le cast intelligent ne vous donnerait qu'un KMutableProperty1<T, *> et vous ne pourriez pas appeler set toute façon car le compilateur ne sait pas quel type accepter comme deuxième paramètre.


0 commentaires

0
votes

lorsque vous avez l'instance de votre objet nécessaire, vous faites simplement -> user.name = "toto"


1 commentaires

C'est OK si je veux définir exactement la propriété "name" sur "toto". Dans mon cas, j'ai un objet avec plus de 20 propriétés et une carte de hachage avec les noms et les valeurs des propriétés à changer dans cet objet. Je peux parcourir la carte de hachage pour obtenir des paires (clé, valeur), mais je ne peux pas appeler la propriété d'instance de classe de données simplement par "utilisateur [clé]"



0
votes

Vous pouvez utiliser la réflexion de style Java si vous ciblez la plate-forme JVM. Pour définir la propriété "name" de l'instance utilisateur de la classe User sur "Alex",

val userName = user.javaClass
    .getMethod("get${field.capitalize()}")
    .invoke(user) as String

Et pour obtenir la propriété "name",

val field = "name"
user.javaClass
    .getMethod("set${field.capitalize()}", String::class.java)
    .invoke(user, "Alex")


0 commentaires