我正在尝试编写一个通用的基本活动,它指定它的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,但它在每个扩展类中实现抽象令牌的开销。
答案 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
}