TL; DR:
Как сделать это менее избыточным (любой подход, который работает, помогает)?
if (personModification.firstName != null) {person.firstName = personModification.firstName}
if (personModification.lastName != null) {person.lastName = personModification.lastName}
if (personModification.job != null) {person.job = personModification.job}
Длинная версия: у меня простая проблема. У меня есть класс Person
:
class Person (val firstName: String?,
val lastName: String?,
val job: String?)
и у меня есть класс под названием PersonModification
:
class PersonModification(val firstName: String?,
val lastName: String?,
val job: String?)
Задача состоит в том, чтобы перезаписать все значения свойств Person
с PersonModification
значений PersonModification
, если свойство PersonModification
не равно null
. Если вам все равно, бизнес-логика этого является конечной точкой API, которая модифицирует Person
и принимает PersonModification
в качестве аргумента (но может изменять все или любые свойства, поэтому мы не хотим перезаписывать действительные старые значения с нулями), Решение этого выглядит так.
if (personModification.firstName != null) {person.firstName = personModification.firstName}
if (personModification.lastName != null) {person.lastName = personModification.lastName}
if (personModification.job != null) {person.job = personModification.job}
Мне сказали, что это избыточно (и я согласен). Псевдокод решения выглядит так:
foreach(propName in personProps){
if (personModification["propName"] != null) {person["propName"] = personModification["propName"]}
}
Конечно, это не JavaScript, так что это не так просто. Мое отражение решения ниже, но imo, лучше иметь избыточность, чем здесь отражать. Каковы мои другие варианты устранения избыточности?
Refelection:
package kotlin.reflect;
class Person (val firstName: String?,
val lastName: String?,
val job: String?)
class PersonModification(val firstName: String?,
val lastName: String?,
val job: String?)
// Reflection - a bad solution. Impossible without it.
//https://stackoverflow.com/info/35525122/kotlin-data-class-how-to-read-the-value-of-property-if-i-dont-know-its-name-at
inline fun <reified T : Any> Any.getThroughReflection(propertyName: String): T? {
val getterName = "get" + propertyName.capitalize()
return try {
javaClass.getMethod(getterName).invoke(this) as? T
} catch (e: NoSuchMethodException) {
null
}
}
fun main(args: Array<String>) {
var person: Person = Person("Bob","Dylan","Artist")
val personModification: PersonModification = PersonModification("Jane","Smith","Placeholder")
val personClassPropertyNames = listOf("firstName", "lastName", "job")
for(properyName in personClassPropertyNames) {
println(properyName)
val currentValue = person.getThroughReflection<String>(properyName)
val modifiedValue = personModification.getThroughReflection<String>(properyName)
println(currentValue)
if(modifiedValue != null){
//Some packages or imports are missing for "output" and "it"
val property = outputs::class.memberProperties.find { it.name == "firstName" }
if (property is KMutableProperty<*>) {
property.setter.call(person, "123")
}
}
})
}
Вы можете скопировать и вставить здесь, чтобы запустить его: https://try.kotlinlang.org/