首页 > 解决方案 > Kotlin如何确保泛型参数是接收器类的超类

问题描述

我尝试实现快速字段访问器功能,并且还想确保指定的类(字段的真正所有者)是接收者类型的超类,因此我将其编写如下:

inline fun <A : B, reified B: Any> A.getProperty (name: String): Any {
    return B::class.java.getDeclaredField(name).apply { isAccessible = true }.get(this)
}

但这使我在调用期间毫无意义地编写接收器类型:

// in SubClass
getProperty<SubClass, BaseClass>("fieldThatIsInBaseClass")

如果在当前类中定义了字段,令我惊讶的是它甚至不需要参数:

// in BaseClass
getProperty("fieldThatIsInBaseClass")

我还尝试向函数添加字段类型参数,但这会破坏上面的代码,并且在每种情况下都必须指定所有参数:

inline fun <A : B, reified B: Any, T> A.getProperty (name: String): T {
    @Suppress("UNCHECKED_CAST")
    return B::class.java.getDeclaredField(name).apply { isAccessible = true }.get(this) as T
}

并举例说明这是如何破坏事物的:

// in a class Example which declares the field
getProperty<Example, Example, Int>("someIntField")

定义字段的类中的理想语法应该是:

getProperty<Int>("someIntField")

对于扩展某些基类的类:

getProperty<BaseClass, Int>("fieldThatIsInBaseClass")

这样的事情可能吗?

标签: genericsreflectionkotlin

解决方案


为什么你需要A?如果您将其替换为B

inline fun <reified B: Any> B.getProperty (name: String): Any {
    return B::class.java.getDeclaredField(name).apply { isAccessible = true }.get(this)
}

它还将接受B.


推荐阅读