代码之家  ›  专栏  ›  技术社区  ›  xinaiz

kotlin如何确保泛型参数是receiver类的超类

  •  0
  • xinaiz  · 技术社区  · 6 年前

    我试图实现quick field accessor函数,还想确保指定的类(字段的真正所有者)是receiver类型的超类,因此编写如下:

    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")
    

    有可能吗?

    1 回复  |  直到 6 年前
        1
  •  1
  •   Alexey Romanov    6 年前

    你为什么需要 A 完全?如果你把它换成 B :

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

    它还可以接受 .