When I iterate over a list of Sprites and check whether they implement UsesObjectPool or not, I am encountering these problems due to type erasure:
*If I try to check its type I get:
Cannot check for instance of erased type: UsesObjectPool
if(it is UsesObjectPool<Sprite>)
{
it.objectPool.releaseObject(it)
}
"required parameter Nothing, found Sprite & UsesObjectPool:
if(it is UsesObjectPool<*>)
{
it.objectPool.releaseObject(it)
}
*If I cast the it to UsesObjectPool, I get:
Type argument is not within its bounds. Expected: UsesObjectPool Found: Sprite
if(it is UsesObjectPool<*>)
{
(it as UsesObjectPool<Sprite>).objectPool.releaseObject(it)
}
The generic class and interface:
interface UsesObjectPool<T> where T :UsesObjectPool<T>, T : Sprite
{
val objectPool: BaseObjectPool<T>
}
abstract class BaseObjectPool<T> where T : UsesObjectPool<T>, T : Sprite
{
fun releaseObject(instance: T)
{
//Implementation
}
}
The problem here is that you are not actually saying that T should be the implementing type (known as Self in some languages). As far as the Kotlin compiler is concerned, T can be any other type that implements UsesObjectPool<T>. This is why you can't pass it to releaseObject.
Here is an example:
class EvilObjectPool<T>: BaseObjectPool<T>() where T : UsesObjectPool<T>, T : Sprite
class Implementation : Sprite(), UsesObjectPool<Implementation> {
override val objectPool: BaseObjectPool<Implementation>
get() = EvilObjectPool()
}
class EvilImplementation : Sprite(), UsesObjectPool<Implementation> {
override val objectPool: BaseObjectPool<Implementation>
get() = EvilObjectPool()
}
Notice that this compiles. Generally we as humans recognise this "self-bound generics" pattern, and will never write something like EvilImplementation, but the compiler doesn't know that :(
Now imagine that it is EvilImplementation. it.objectPool.releaseObject would accept an Implementation, but you are giving it an EvilImplementation!
Anyway, I think you'd need to re-think your design, since Kotlin does not support Self as in some other languages.
See also a similar problem in Java.