我正在尝试编写一个函数,为任何类型生成属性和值的映射
inline fun <reified T : Any> T.propertiesMap() {
for (property in this::class.memberProperties) {
property.get(this)
}
}
我在property.get(this)
中遇到了关于
out-projection类型[...]禁止使用'public abstract fun get(接收器......
)
答案 0 :(得分:2)
问题是,this::class
会产生KClass<out T>
而不是KClass<T>
,这是在T
来电中使用property.get(...)
类型的任何内容所需要的。所以你可以做一个未经检查的演员来做你想做的事情:
fun <T : Any> T.propertiesMap() {
@Suppress("UNCHECKED_CAST")
for (property in (this::class as KClass<T>).memberProperties) {
property.get(this)
}
}
这不需要函数是内联函数或者是reified类型参数。否则,您可以将功能更改为使用T::class
而不是this::class
来创建匹配的KClass<T>
。
inline fun <reified T : Any> T.propertiesMap() {
for (property in T::class.memberProperties) {
property.get(this)
}
}
答案 1 :(得分:1)
如果您使用的是您正在进行修改的类型而不是该类型的实例,则方差问题将会消失。当您致电T::class.memberProperties
时,您会收到Collection<KProperty<T, *>>
,这是我认为您想要的。另一方面,如果您在实例(this
)上调用该内容而不是类型,则会返回Collection<KProperty<out T, Any?>>
,这是您的外部差异问题的来源。
inline fun <reified T : Any> T.propertiesMap() {
for (property in T::class.memberProperties) {
property.get(this)
}
}
基本上,您需要执行T::class
而不是this::class
才能获得正确的收集。我已经将您的代码保留为原样,否则因为我不清楚您希望此功能执行什么操作,但我怀疑您可以放弃for循环以支持map
调用。< / p>