Generics 为什么我的领域Kotlin泛型解决方案没有按预期工作?

Generics 为什么我的领域Kotlin泛型解决方案没有按预期工作?,generics,kotlin,realm,Generics,Kotlin,Realm,我知道Realm还没有直接支持泛型。我一直在试图想出一个变通办法,因为它将大大减少我的项目中重复的代码。(我有许多扩展基本回购的回购协议和许多只因RealmObject扩展类型不同的函数) 我有一个相当好的解决方案: open class BaseRepository(private val realm: Realm) { fun <T : RealmModel> get(ofType: Class<T>, id: Long): T? { ret

我知道Realm还没有直接支持泛型。我一直在试图想出一个变通办法,因为它将大大减少我的项目中重复的代码。(我有许多扩展基本回购的回购协议和许多只因RealmObject扩展类型不同的函数)

我有一个相当好的解决方案:

open class BaseRepository(private val realm: Realm) {

    fun <T : RealmModel> get(ofType: Class<T>, id: Long): T? {
        return realm.where(ofType).equalTo("id", id).findFirst()
    }  
}
我试图通过在构造函数中传递类类型而不是函数param来进一步改进这一点:

open class BaseRepository<T : RealmModel?>(private val realm: Realm, private val ofType: Class<T>) {

    fun <T : RealmModel> get(id: Long): T? {
        return realm.where(ofType).equalTo("id", id).findFirst()
    }
}
我已经做了各种尝试,以使这项工作,但我还没有成功

问题:

  • 为什么我不能在构造函数param中传递ofType:Class,但我可以在函数param中传递

  • 有人知道怎么修吗

  • 我现在所做的一切看起来确实有效,而且我所有的测试都通过了,这有什么问题吗

  • 有没有人有更好的解决方案,例如使用kotlin扩展方法

  • 谢谢,
    Paul.

    实际上,如果将类传递给超类,那么就不再需要为函数使用模板参数

    open class BaseRepository<T : RealmModel>(private val realm: Realm, private val ofType: Class<T>) {
    
        fun get(id: Long): T? =
            realm.where(ofType).equalTo("id", id).findFirst()
    }
    
    或者,如果您使用的是较新版本的Realm(4.3.1+),则可以将其更改为

    import io.realm.kotlin.where
    
    open class BaseRepository(private val realm: Realm) {
    
        inline fun <reified T : RealmModel> get(id: Long): T? =
            realm.where<T>().equalTo("id", id).findFirst()
    }
    
    import io.realm.kotlin.where
    开放类BaseRepository(私有val领域:领域){
    内联乐趣获取(id:Long):T=
    realm.where().equalTo(“id”,id).findFirst()
    }
    
    我只是想给你一些想法,但从技术上讲,你可以把它变成一个扩展函数

    inline fun <reified T : RealmModel> Realm.get(id: Long): T? =
        where<T>().equalTo("id", id).findFirst()
    
    inline fun Realm.get(id:Long):T=
    其中().equalTo(“id”,id).findFirst()
    
    现在你可以做了

    val dog = realm.get<Dog>(12L)
    
    val dog=realm.get(12L)
    
    这太棒了,谢谢。我同意第一个建议,因为它允许我在构建存储库时只指定一次类类型,我可以在整个代码库中调用repo.get(12L),并且该类型基于特定的存储库而已知,而无需在调用时调用它。我试图按照建议减少“::class.java”,但出现了一些错误,因此我将继续使用它。这不仅回答了我的问题,再次感谢!
    import io.realm.kotlin.where
    
    open class BaseRepository(private val realm: Realm) {
    
        inline fun <reified T : RealmModel> get(id: Long): T? =
            realm.where<T>().equalTo("id", id).findFirst()
    }
    
    inline fun <reified T : RealmModel> Realm.get(id: Long): T? =
        where<T>().equalTo("id", id).findFirst()
    
    val dog = realm.get<Dog>(12L)