Kotlin中的通用类类型用法

时间:2017-12-20 07:56:14

标签: android generics kotlin

我正在尝试编写一个通用的基本活动,它指定它的ViewModel类型是一个通用参数:

abstract class BaseActivity<T : ViewModel> : AppCompatActivity()

现在我正在尝试为我的ViewModel编写一个惰性初始化属性:

val viewModel by lazy { ViewModelProviders.of(this, getFactory()).get(T) }

显示的错误是Type Parameter T is not an expression

同样使用::class::class.java也无济于事。任何人都可以解释这个问题吗?

编辑:我尝试使用这样的内联函数:

inline fun <reified T : ViewModel?> AppCompatActivity.obtainViewModel(factory: ViewModelProvider.Factory): T {
    return ViewModelProviders.of(this, factory).get(T::class.java)
}

并像这样使用它:

abstract class BaseActivity<T> : AppCompatActivity() {
    val viewModel by lazy { obtainViewModel<T>(getFactory()) 
}

现在我收到错误,T不能用作具体参数。

EDIT2:到目前为止,最好的解决方案似乎是:Link,但它在每个扩展类中实现抽象令牌的开销。

2 个答案:

答案 0 :(得分:2)

您的类有一个类型参数T,不幸的是它在运行时被删除。因此,调用get(T)不起作用(我想该方法实际上需要Class?)。

您似乎已经注意到了这一点,因此尝试通过将处理封装到使用reified类型的方法来修复它。但是,您无法将T作为已知参数传递,因为在调用reified类型的方法时,此类型已被删除。因此,obtainViewModel<T>也无效。您可以做的是将T用于普通的泛型方法,如下所示:

class Typed<T> {
    val lazyProp by lazy {
        listOf<T>()
    }
}

答案 1 :(得分:0)

也许有点晚,但是我想这可能是实现它的一种优雅方法:

abstract class BaseActivity<T : ViewModel>(
    private var modelClass: Class<T>) : AppCompatActivity() {

    val viewModel by lazy { 
        ViewModelProviders.of(this, getFactory()).get(modelClass) 
    }

}

然后

class SampleActivity : BaseActivity<SampleViewModel>(SampleViewModel::class.java) {
    // use viewModel from here
}