【问题标题】:How can I get property reference from an class reference or generic type?如何从类引用或泛型类型中获取属性引用?
【发布时间】:2020-10-24 20:40:26
【问题描述】:

我正在尝试用 niceAssign() 替换 assign() 方法:

    class Builder<T : Any>(val kClass: KClass<T>) {
        fun <K> assign(prop: KProperty1<T, K>, value: K): Builder<T> = TODO("doing other stuff here")
        fun <K> niceAssign(call: KClass<T>.() -> Pair<KProperty1<T, K>, K>) : Builder<T> {
            val (prop, value) = call(kClass)
            return assign(prop, value)
        }
    }

    val builder = Builder(Data::class)
    builder.assign(Data::someProperty, "some value") // (1)
    builder.niceAssign { ::someProperty to "some value" } // (2)

由于 builder 对象是使用 Data 类生成的,因此我不需要在传递属性引用时明确指出 Data 类。分配方法已经知道该属性属于哪个类。所以我不想每次在assign方法中都写“Data::”(就像在代码(1)中一样),但我想将“Data::”作为niceAssign参数的接收器属性传递,所以我可以参考::来自“this”对象的一些属性。

这段代码 sn-p 不起作用,因为我将 K​​Class 作为接收者传递,而 KClass 没有 T 的属性引用。 那么,有什么方法可以让它发挥作用吗?

【问题讨论】:

    标签: kotlin generics reflection


    【解决方案1】:

    如果你想将属性引用传递给高阶函数,那么它应该是一个以T 作为接收者的函数。

    在所描述的情况下,它需要是:

    fun <K> niceAssign(call: T.() -> Pair<KProperty0<K>, K>) : Builder<T> {
    ...
    }
    

    但要“解包”传递给niceAssign 参数(以便它们可以进一步传递给assign 函数),您将需要T 的实例,例如:

    val (prop, value) = call(kClass.createInstance())
    

    同样结果也不能按原样传递给assign 方法,因为prop 参数类型不匹配,所以这种方法需要一些额外的代码返工。

    【讨论】:

    • 谢谢,这行得通。我也想过。但是有一个问题,您必须在使用该构造函数之前手动创建 T 的实例。对于任意类(具有非空非默认字段),您既不能调用 kClass.objectInstance 也不能调用 kClass.createInstance()。因此,唯一的方法是将引用对象传递给 Builder 构造函数,但处理该问题的方法非常奇怪。
    猜你喜欢
    • 2023-04-08
    • 2015-03-11
    • 2020-01-29
    • 1970-01-01
    • 2012-04-17
    • 1970-01-01
    • 1970-01-01
    • 2018-02-16
    • 2021-08-13
    相关资源
    最近更新 更多