web-dev-qa-db-ja.com

Kotlinでジェネリックメソッドに型を渡す方法は?

以下のような一般的な方法があります

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

変数Tタイプを使用してこのメ​​ソッドを呼び出すにはどうすればよいですか?

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

実行時に、ジェネリック型Tがどうなるかわかりません。私はtypesから型を取得しており、ジェネリックgetSomethingメソッドでそれを渡す必要があります。

使用事例

複数のテーブルを持つデータベースを呼び出したいのですが。モデルの例は次のとおりです

class User{

}

class Student{

}

すべての呼び出しクエリは基本的に同じなので、データベースを呼び出してデータを取得するための汎用的なメソッドが必要です。

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

したがって、上記のメソッドを呼び出すと、ループ内では、TypeUserまたは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>
}

どうすれば達成できますか。

6
musooff

私は具体的なタイプに固執します

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()
}

しかし、それでもオーバーヘッドです。なぜgetUserまたはgetStudentsを直接使用しないのですか。

1
Dmitry