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