Home > Software design >  Avoid erasing generics in Runtime with Generics in Kotlin
Avoid erasing generics in Runtime with Generics in Kotlin

Time:06-21

I have a "repository" that encapsulates some datastore, my goal is to get values from there by using generics. For example : repo.retrieve<String>("some_key")

However I keep getting : Cannot use 'T' as reified type parameter. Use a class instead.

interface IRepo {
    fun <T: Any> retrieve(key: String): T?
}

class MyRepo: IRepo {

    private var sharedPrefs

    override fun <T: Any> retrieve(key: String): T? {
          return getByType<T>(key) --> here T causes : Cannot use 'T' as reified type parameter. Use a class instead.
    }

    private inline fun <reified T> getByType(key: String): T? {
        return when(T::class) {
            is String -> sharedPrefs.getString(key)
            ...
        }
    }
}

Is there a way or some workaround to make this work?

CodePudding user response:

Add a Class parameter in your interface defintion. You can create an inline extension function overload with reified type for convenience.

interface IRepo {
    fun <T: Any> retrieve(cls: Class<T>, key: String): T?
}

inline fun <reified T: Any> IRepo.retrieve(key: String): T? = 
    retrieve(T::class.java, key)

class MyRepo: IRepo {

    private var sharedPrefs

    override fun <T: Any> retrieve(cls: Class<T>, key: String): T? {
        return getByType(cls, key)
    }

    private fun <T> getByType(cls: Class<T>, key: String): T? {
        return when(cls) {
            String::class.java -> sharedPrefs.getString(key)
                // ...
        }
    }
}
  • Related