Let's take a look at your example
class Mediator {
//It does't work! My question is about this function.
inline fun <reified T : Container<C>> mediate(string: String): T {
if (C::class == Child1::class)
//Do something
if (C::class == Child2::class)
//Do something else
}
}
class UseExample : Mediator() {
fun example1(): Container<Child1> {
return mediate("test1") // your mediate function does not take
// any parameters to determine the generic type
}
fun example2(): Container<Child2> {
return mediate("test2")
}
}
To perform something with the type C
which is used to create Container<C>
and perform something with the result type which you represent as T : Container<C>
you only need to know the C
. Since reified
can only be used to keep the type if it is known during the compile time at the call site, rewrite your function signature like this.
inline fun <reified C> mediate(string: String): Container<C> {
// now you know the C and you know the T which is Container<C>
if (C::class == Child1::class) ...
// Since T depends on C, you can only check the C type to perform logic
}
Use it like following
fun example1(): Container<Child1> {
return mediate<Child1>("test") // Note that know your C
// type is known at the function call therefore compiler
// can substitute it with exact type
}
Here is my minimal example from Kotlin Playground
class Container<T>(t: T) {
val smth : T = t
}
class Mediator {
inline fun <reified C> mediate(string: String): Container<C> {
if (C::class == Int::class) {
println("Int")
return Container<Int>(1) as Container<C>
}
throw IllegalStateException("Yopta")
}
}
fun main() {
val m = Mediator()
m.mediate<Int>("ABC") // Output is "Int"
}