通过反射,我需要区分有上下文的方法和没有上下文的方法(Kotlin1.8.0)。
假设我们有下面的虚拟上下文和一个有两个函数的类-一个有上下文,第二个没有。
class Context(val a: Int)
class Foo {
context (Context)
fun bar() = a
fun baz() = 1
}
在运行时,我们不知道哪个方法是哪个方法,所以让我们尝试通过反射来区分它们。
val foo = Foo()
val barMethod = foo::class.memberFunctions.first { it.name == "bar" }
println("barMethod has ${barMethod.parameters.size} parameter(s)")
val bazMethod = foo::class.memberFunctions.first { it.name == "baz" }
println("bazMethod has ${bazMethod.parameters.size} parameter(s)")
问题是,两者都返回一个参数(在所有其他公共属性中都是相同的)。但很明显,当调用时,如果只提供一个参数,bar
将失败。如果按预期调用,它可以工作。
// println(barMethod.call(foo)) -- fails
println(bazMethod.call(foo))
println(barMethod.call(foo, Context(6))
在调试时,我发现barMethod(KCallableImpl)上实际上有一个内部属性descriptor
,它包含contextReceiverParameters
属性,正确显示barMethod为1,bazMethod为0。但它不可访问。
有什么想法,如果有任何支持的方式通过反射检索上下文接收者的信息,或者它只是还没有实现?
1条答案
按热度按时间kr98yfug1#
首先,定义注解类:
然后,用下面的注解来注解具有上下文接收器的函数:
现在你可以使用下面的代码来检查一个函数是否有上下文接收器:
这将输出:
请记住,这种方法依赖于手动将**@WithContext**注解添加到具有上下文接收器的函数中。在未来的Kotlin版本中,当功能变得稳定并且反射变得更稳定时,可能会有更直接的方法来访问上下文接收器参数。