Sometimes we need to preserve generic types in run...
# language-proposals
e
Sometimes we need to preserve generic types in runtime, for example if we want to be able to distinguish between
Container<String>
and
Container<Int>
. A one particular solution (although not really flexible) would to subtype
Container<T>
with statically typed
StringContainer : Container<String>
and
IntContainer : Container<Int>
. The problem is, as aforementioned, it's not really flexible and we have to do it by hand. What if we could somehow tell compiler that we want to generate such subclasses with statically saved type parameter for every class that uses original, generic class? E.g.
Copy code
open class Container<sticky T> {
  ...
}
...
val sc = Container<String>()
if (sc is Container<Int>) { // unreachable }
Under the hood would turn into
Copy code
val sc = StringContainer()
if (sc is Container) { ... }
Theoretically, it is possible to track down all the types which generic type is parameterized with in compile-time; To avoid some problems with subclassing this functionality could be restricted for non-final classes. Also there could be problems with multiple type parameters. So, thoughts? Would this be useful, what more problems can this bring, is there ways to enhance it?
r
Unless I'm misunderstanding your intent, I believe the common solution to this problem is to pass in the
Class<T>
, not to subclass
Container
.
e
Never seen it. Could you provide an example please?
r
Copy code
class Container<T>(val type: Class<T>)
Then you can just check the class
Copy code
if (container.type == String::class.java) {
    ...
}
You can also create an inline function in Kotlin like so to make the call a little cleaner:
Copy code
inline fun <reified T: Any> Container() = Container(T::class.java)
so you can still use
Copy code
val sc = Container<String>()
e
I think this called “reified” (not “sticky”) and is currently supported for inline functions only (but not supported for classes). The solution by @Ruckus is a way to go.
e
I now realize I was referring to something like C++'s templates, so I don't think it's reifying. Also inline functions don't really help in defining what type parameter are we dealing with in collections, for instance, unless I'm missing something.