generics - 当类型参数在声明站点协变时,强制类型参数在使用站点保持不变

标签 generics reflection kotlin covariance generic-variance

我正在 KProperty1 上构建扩展功能。该函数需要接受扩展属性值类型 ( R ) 的参数,即使 KProperty1类型参数 R 是协变的.

下面是一个稍微做作的示例,尽管我的使用更合法。

data class Data(val value: String)

fun <V> KProperty1<*, V>.setMagically(value: V) {
    this.javaField?.set(null, value)
}

fun test() {
    // I would like this to fail to compile
    Data::value.setMagically(190)
}

编译器似乎正在推断类型 Any对于 R ,这是完全有效的,因为 KProperty1<*, String> : KProperty1<*, Any>

我想说的是,对于我的具体情况,我实际上想要 V保持不变。我知道你可以使用outin作为方差加宽器,但我无法弄清楚如何指定我想要覆盖 KProperty1 上的协变注释对于这种情况具有不变性。

值得注意的是,它与 KMutableProperty1 配合得很好。 ,因为它在 R 中是不变的。但我的代码也需要使用不可变的属性。

对于上下文,我正在构建一些生成数据库查询的东西,这就是为什么我需要该值成为属性类型的子类,即使我实际上没有写入该属性,但这个问题更一般比我具体的属性(property)处理案例。

最佳答案

目前这在 Kotlin 中是不可能的。事实上,有一个内部注释可以实现此行为(如果推断出 Any,尽管在​​调用站点中没有提到它,则导致编译器报告错误),并且它在 kotlin-stdlib,但仍然不鼓励在标准库之外使用它。

我们计划公开此注释。更多详情请查看KT-13198 .

关于generics - 当类型参数在声明站点协变时,强制类型参数在使用站点保持不变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47191898/

相关文章:

kotlin - Android Studio要求在成员已声明后声明成员

android - Android Room强制通过自动增量值重写属性

kotlin - 有没有办法通过委托(delegate)实现 `Comparable<T>` ?

c# - 无法从用法中推断出类型参数

java - 这个通用 Guice 绑定(bind)方法的 TypeLiteral 等价物有什么问题?

.net - 如何从 .net 中的数组类型获取数组项类型

c# - 如何在 C# 中查找调用方法的全名

java - 将 JAXB、泛型和反射结合到 XML 序列化我所有的 Java 类

c# - Dictionary<string,object> 是将未知变量集合传递给构造函数的最佳方式吗?

c# - 有没有办法在运行时获取构造函数参数的值