当 T 为“Any”类型时,通用参数需要类型“Nothing”

bus*_*ush 2 generics reflection kotlin

我是一名新的 Kotlin 程序员,我遇到了与泛型相关的问题

在以下代码中,我收到错误it.get(this)“类型不匹配。必需:无。找到:任何。

inline fun <reified T : Any> Any.getPropertiesWithType() =
    this::class.memberProperties
        .filter { it.returnType.isSubtypeOf(T::class.starProjectedType) }
        .map {
            it.isAccessible = true
            it.get(this) as T
        }
Run Code Online (Sandbox Code Playgroud)

这很令人困惑,因为memberProperties返回 aCollection<KProperty1<T, *>>其中 T 是 的类型,在我的例子中this就是这样。采用相同类型 T 的一个参数,因此我希望可以顺利通过。AnyKProperty1.get()Any

我注意到的一件事是,it过滤器和映射中都是类型KProperty<out Any, *>>,但memberProperties没有输出方差。

如果我替换this::classthis.javaClass.kotlin,它可以正常工作而不会出现错误,但这似乎是一个非常糟糕的方法。

如果有人知道解决此问题的方法或完全不同的策略,我们将不胜感激。我是 Kotlin 的新手,有时仍然以 Java 的方式做事。

Swe*_*per 5

this::class类似于this.getClass()Java 中,它返回一个KClass<out Any>( Class<? extends Object>Java 中)。毕竟,仅仅因为 的类型thisAny,它的运行时类型可能不是Any- 它可能是 的任何子类Anyout Any抓住了这个想法。

因此, 的memberPropertiesthis::class是 的集合KProperty1<out Any, *>

就像您不能向 using 添加任何内容一样MutableList<out Any>add您也不能标记geta 的值- 输入参数的类型。另一种思考方式是,该属性可以位于 的任何子类上,尝试使用 来获取该属性(这只是一个 ),显然是行不通的。KProperty1<out Any, *>outAnythisAny

我会将未经检查的演员移至it

(it as KProperty1<Any, T>).get(this)
Run Code Online (Sandbox Code Playgroud)

至于为什么.javaClass有效,是因为javaClass实际上给了你一个Class<Any>,而不是Class<out Any>。IMO,这没有多大意义,但事实就是如此。