Chris Legge
Chris Legge

Reputation: 789

why do i hav to cast this in my Kotlin generic

still trying to get the hang of generics in kotlin, i how can i write this to avoid the unchecked cast.

 class DBEntityUtil<T:DBEntity, S:Model> {
    fun entityListToModelList(entityList:List<T>): List<S>{
        val returnList:MutableList<S> = mutableListOf()
        entityList.forEach{entity:T ->
            returnList.add(entity.toModel() as S)
        }
        return returnList
    }
}

and the toModel()

interface IngestsModel {
    fun toModel(): Model
}

Upvotes: 0

Views: 85

Answers (1)

zapl
zapl

Reputation: 63955

S is any subclass of Model and toModel can only guarantee to return a Model. If you want an S you have to cast. If you just want Model you can drop the generic S and should have no problem using fun entityListToModelList(...): List<Model>.

However if you want to make it work like shown you have to use a setup like

interface Model
interface DBEntity<S:Model> {
    fun toModel(): S
}

which ties the DBEntity to the type of S. That can be used like

class DBEntityUtil<S:Model, T:DBEntity<S>> {
    fun entityListToModelList(entityList:List<T>): List<S>{
        val returnList:MutableList<S> = mutableListOf()
        entityList.forEach{entity:T ->
            returnList.add(entity.toModel())
        }
        return returnList
    }
}

And used for example like

class TestModel: Model
class TestDbEntity : DBEntity<TestModel> {

    override fun toModel(): TestModel {
        return TestModel()
    }

    companion object {
        val util = DBEntityUtil<TestModel, TestDbEntity>()
        fun test() = util.entityListToModelList(listOf(TestDbEntity()))
    }
}

https://pl.kotl.in/Bkpc92vjm

Upvotes: 3

Related Questions