Search code examples
genericskotlininterfacetype-erasurekotlin-reified-type-parameters

kotlin reified generic in virtual function


In my concrete class I would like to have a function that has the following signature.

inline fun <reified T : Comparable<T>> get(key: String): T

However I want to extract an interface for this class so I could swap implementations. However I'm not sure how to go about it as I can't mark virtual functions as inline.

So far I have this interface:

interface ModuleSettings {

    fun <T : Comparable<T>> get(key: String) : T

}

And this concrete class

class DefaultModuleSettings : ModuleSettings {

    override inline fun <reified T : Comparable<T>> get(key: String): T {
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
    }
}

But now the compiler complains that im trying to override the generic type with reified keyword. Is there any way I can achieve this pattern?


Solution

  • You can't inline interface functions, but you can take the class object as a parameter. To still get the same function signature, you could create an inline reified overload in DefaultModuleSettings that delegates to the interface function. You can't call that if you only have a reference with the interface-type though.

    Something like this:

    interface ModuleSettings {
        fun <T : Comparable<T>> get(key: String, clazz: KClass<T>) : T
    }
    
    class DefaultModuleSettings : ModuleSettings {
    
        override fun <T : Comparable<T>> get(key: String, clazz: KClass<T>): T {
            TODO("not implemented")
        }
    
        inline fun <reified T : Comparable<T>> get(key: String): T = get(key, T::class)
    
    }
    

    Edit:

    Making the inline function an extension function is better:

    inline fun <reified T : Comparable<T>> ModuleSettings.get(key: String): T = get(key, T::class)