给出以下基类:
public abstract class PurchaseSystemControllerBase<TController, TViewModel> : IInitializable
where TController : PurchaseSystemControllerBase<TController, TViewModel>
where TViewModel : PurchaseSystemViewModelBase<TController, TViewModel> {
protected TViewModel ViewModel { get; private set; }
...
}
public abstract class PurchaseSystemViewModelBase<TController, TViewModel> : ViewModelBase
where TController : PurchaseSystemControllerBase<TController, TViewModel>
where TViewModel : PurchaseSystemViewModelBase<TController, TViewModel> {
protected TController Controller { get; private set; }
...
}
具体实施如下:
public sealed class PurchaseSystemController : PurchaseSystemControllerBase<PurchaseSystemController, PurchaseSystemViewModel> {
...
}
public sealed class PurchaseSystemViewModel : PurchaseSystemViewModelBase<PurchaseSystemController, PurchaseSystemViewModel> {
...
}
有没有办法简化这个以便可以进行以下操作?
public sealed class PurchaseSystemController : PurchaseSystemControllerBase<PurchaseSystemViewModel> {
...
}
public sealed class PurchaseSystemViewModel : PurchaseSystemViewModelBase<PurchaseSystemController> {
...
}
答案 0 :(得分:3)
不,不幸的是 - 至少,不是我意识到的,并没有失去某种类型的安全性。 我在my Protocol Buffers port中有一个非常类似的设置,在消息类型和相应的构建器类型之间。
如果您对使用一些非泛型基类型声明ViewModel
和Controller
属性感到高兴,那就没问题 - 但如果您需要两者完全了解相应的类型,那么因为这种混乱而离开了。
(您可能需要考虑ViewModel和Controller 是否彼此都知道,请注意。)
答案 1 :(得分:1)
不,在保持您拥有的完全强类型的同时,这是不可能的。以下是如何将其缩减为更基本的输入的示例:
public abstract class PurchaseSystemControllerBase : IInitializable {
protected PurchaseSystemViewModelBase ViewModel { get; private set; }
}
public abstract class PurchaseSystemControllerBase<TViewModel>
: PurchaseSystemControllerBase
where TViewModel : PurchaseSystemViewModelBase {
// note: property implementations should prevent this and base.ViewModel
// from getting out of sync
protected new TViewModel ViewModel { get; private set; }
}
public abstract class PurchaseSystemViewModelBase : ViewModelBase {
protected PurchaseSystemControllerBase Controller { get; private set; }
}
public abstract class PurchaseSystemViewModelBase<TController>
: PurchaseSystemViewModelBase
where TController : PurchaseSystemControllerBase {
// note: property implementations should prevent this and base.Controller
// from getting out of sync
protected new TController Controller { get; private set; }
}
public sealed class PurchaseSystemController
: PurchaseSystemControllerBase<PurchaseSystemViewModel> {
}
public sealed class PurchaseSystemViewModel
: PurchaseSystemViewModelBase<PurchaseSystemController> {
}
这可能就足够了,特别是考虑到这些是protected
属性。