web-dev-qa-db-fra.com

Comment passer un type à une méthode générique dans Kotlin?

J'ai une méthode générique comme ci-dessous

private fun <T> getSomething(): T {
    return "something" as T
}

Comment puis-je appeler cette méthode avec un type de variable T?

val types = arrayListOf<Type>(String::class.Java, Boolean::class.Java)
types.forEach { type ->
    val something = getSomething<type>() // Unresolved reference: type
}

Au moment de l'exécution, je ne sais pas quel serait le type générique T. J'obtiens le type de types et je devrais le passer avec la méthode générique getSomething.

Cas d'utilisation

Je veux appeler la base de données qui a plusieurs tables. Des exemples de modèles sont comme ceci

class User{

}

class Student{

}

Étant donné que toutes les requêtes d'appel sont essentiellement les mêmes, je veux avoir une méthode générique pour appeler la base de données et obtenir des données.

private fun <T> getData(model: String): List<T>?{
    return when(model){
        "user" -> getUsers()
        "student" -> getStudents()
        else -> null
    }
}

Donc, quand j'appelle la méthode ci-dessus. Dans ma boucle, je veux passer Type comme User ou Student.

val types = arrayListOf<Type>(User::class.Java, Student::class.Java)
types.forEach { type ->
    val data = getData<type>(type.javaClass.simpleName) // Unresolved reference: type in <type>
}

Comment puis-je y parvenir.

6
musooff

Je m'en tiendrai aux types de béton comme

import kotlin.reflect.KClass

interface IBaseData
interface IDataTable<out T> where T : IBaseData
{
    fun getData(): List<T>
}

class User : IBaseData
class Student : IBaseData

class UserTable : IDataTable<User>
{
    override fun getData(): List<User>
    {
        return listOf(User())
    }
}

class StudentTable : IDataTable<Student>
{
    override fun getData(): List<Student>
    {
        return listOf(Student())
    }
}

inline fun <reified T: IBaseData> getDataTable() : IDataTable<T>?
{
    return when(T::class)
    {
        User::class -> UserTable() as IDataTable<T>
        Student::class -> StudentTable() as IDataTable<T>
        else -> null
    }
}

fun main()
{
    var user = getDataTable<User>()?.getData()
    var student = getDataTable<Student>()?.getData()
}

Mais quand même, c'est une surcharge, pourquoi ne pas utiliser directement getUser ou getStudents

1
Dmitry