antonkeks
02/17/2021, 9:19 PMfun <T: Any> T.toValuesSkipping(vararg skip: KProperty1<T, *>): Map<String, Any?> =
(this::class.memberProperties - skip)
.filter { it.javaField != null }.map { it.name to it.get(this) }.toMap()antonkeks
02/17/2021, 9:20 PM(it as KProperty1<T, Any?>).get(this)rnett
02/17/2021, 9:21 PMantonkeks
02/17/2021, 9:22 PMantonkeks
02/17/2021, 9:23 PMantonkeks
02/17/2021, 9:25 PMMarc Knaup
02/17/2021, 9:28 PM.memberProperties?antonkeks
02/17/2021, 9:29 PMantonkeks
02/17/2021, 9:30 PMMarc Knaup
02/17/2021, 9:34 PMout T, which means that get(…) expects either T or a specific subclass of T. And the only valid type for that is Nothing.antonkeks
02/17/2021, 9:34 PMfun <T: Any> T.toValues(): Map<String, Any?> = this::class.memberProperties.map { it.name to it.get(this) }.toMap()
How to compile this without casts?Marc Knaup
02/17/2021, 9:36 PMthis::class you lose type information.ephemient
02/17/2021, 9:38 PMinline fun <reified T : Any> T.toValues(): Map<String, Any?> =
T::class.memberProperties.associate { it.name to it.get(this) }
is one way to keep type informationMarc Knaup
02/17/2021, 9:40 PMthis is T (or any subclass) and this::class is KClass<out T> means the KClass of T (or any subclass).
get() expects “T or any subclass” and this is “T or any subclass”. The compiler doesn’t know that both are the same subclass.
If you are able to use reified and thus T::class then you get KClass<T> which means the KClass of exactly T.antonkeks
02/17/2021, 9:50 PMephemient
02/17/2021, 9:52 PMfun T.getClass(): KClass<T> = this::class
cannot be correct, as if you call it within a
val foo: Any = 1
val fooClass = foo.getClass()
you'd end up with fooClass: KClass<Any> which is not correctMarc Knaup
02/17/2021, 9:53 PM