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 )
3 Réponses :
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.
lorsque vous avez l'instance de votre objet nécessaire, vous faites simplement -> user.name = "toto"
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é]"
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")