Animesh Sahu
Animesh Sahu

Reputation: 8096

How to pass a reified parameter to some other function when current function can't be inline (but we have Reflections)?

Lets pretend we have an interface which defines the storage of data in some database by serializing them into json.

interface StorageApi {
    suspend fun store(key: String, value: Any)
    // inline suspend fun <reified T: Any> get(key: String): T // reification is not possible in interfaces since we can't inline them
    suspend fun <T: Any> get(key: String, kClass: KClass<T>): T // so I have to stick with some other way, like reflection.
}

And then we have an implementation of the method:

override suspend fun <T : Any> get(key: String, kClass: KClass<T>): T {
    val value = // some query to database
    return Klaxon().parse<T>(value) // obviously error by compiler since T goes through type-erasure
}

Here I cannot use T as it would go through Type-erasure at runtime. I have reflection but don't know how to use it in this purpose. The Klaxon.parse() function does not accept KClass for getting types.

Is there any way to bypass these or make some utility to use reflection in this purpose, or any other possible workarounds?

Upvotes: 0

Views: 404

Answers (1)

zsmb13
zsmb13

Reputation: 89548

I am fairly sure that if you break the inlined reification chain at any point, and start working with classes (KClass instances, that is), there is unfortunately no going back, exactly for the reasons you've described.

What's even worse is that a KClass can't hold type parameters, so if your reified parameter was a List<Something> for example, then you've lost information there already - another reason for no going back to reification.

The sad conclusion is that you probably have to deal with KClass in a case like this.

Upvotes: 1

Related Questions