generics - 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")
这样的事情可能吗?
解决方案
为什么你需要A
?如果您将其替换为B
:
inline fun <reified B: Any> B.getProperty (name: String): Any {
return B::class.java.getDeclaredField(name).apply { isAccessible = true }.get(this)
}
它还将接受B
.
推荐阅读
- r - 使用 aws.s3 包从 AWS S3 一次读取多个 CSV 文件对象
- php - 如何修复重置类型输入并不能真正重置所有表单?
- c# - 连接数据库 Sql server 数据库 2000
- android - Socket.IO 连接到 Mac
- android - Visual Studio 认为我没有安装 Hyperv。为什么?
- node.js - 参考错误:D:\nodejs\crud\views\employee\addOrEdit.ejs:8
- qt - Qt Creator中输入if/then条件或函数时如何从()跳转到{}?
- python - Wagtail:挂钩更改子页面的顺序
- java - 泛型通配符方法的编译错误
- assembly - 消除 Intel 语法中寄存器名称的歧义