Kotlin允许您扩展泛型类型类的具体实例。例如,假设我具有以下类Foo
,具有扩展功能Foo<Int>.bar()
和Foo<String>.bar()
:
class Foo<T>(t: T) {
val a: String = "bar"
val b: Int = 111
}
fun Foo<Int>.bar() = a
fun Foo<String>.bar() = b
fun main(args: Array<String>) {
val stringBar: String = Foo(1).bar()
val intBar: Int = Foo("").bar()
}
是否可以在没有扩展功能的情况下实现此行为,如果可以,如何将扩展功能转换为成员?是否可以不重命名或更改类型签名?
答案 0 :(得分:1)
您可以使用 reified 通用参数创建 inline 成员函数:
class Foo<T>(t: T) {
val a: String = "bar"
val b: Int = 111
inline fun <reified T, E> member(): E? {
var r: E? = null
when(T::class) {
String::class -> r = b as E
Int::class -> r = a as E
}
return r
}
}
fun main(args: Array<String>) {
val str = Foo(1).member<Int, String>()
val i = Foo("").member<String, Int>()
}
但是扩展函数在您的情况下更好:它们是类型安全的,更简洁和可读的。
答案 1 :(得分:1)
否,这是不可能的(当前接受的答案与您的代码完全不一样)。
答案 2 :(得分:1)
使用反射,您不必自己在类型和属性之间进行映射。
成员函数propertyValue()
将返回具有通用参数或null
类型的第一个属性的值。
class Foo {
val a: String = "bar"
val b: Int = 111
inline fun <reified T> propertyValue() = Foo::class.memberProperties.firstOrNull {
it.returnType == T::class.createType()
}?.get(this)
}
Foo().propertyValue<Int>()) // 111
Foo().propertyValue<String>()) // bar
Foo().propertyValue<Double>()) // null
您当然可以扩展此功能,以便为您提供所需类型T
的所有属性的值(例如,如果您有多个Int
属性)。