简化c#中的循环泛型约束
本文关键字:泛型 约束 循环 简化 | 更新日期: 2023-09-27 18:19:19
给定以下基类:
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> {
...
}
不,不幸的是没有-至少,我不知道,在不失去一些类型安全的情况下。在我的Protocol Buffers端口中,在消息类型和相应的构建器类型之间,我有一个非常相似的设置。
如果你很乐意用一些非泛型的基本类型声明ViewModel
和Controller
属性,那么这很好-但是如果你需要这两个属性确切地知道相应的类型,你就会留下这种混乱。
(注意,您可能需要考虑ViewModel和Controller 是否应该都知道彼此)
不,在保持完全强类型的情况下,这是不可能的。下面是一个示例,说明如何将其简化为更基本的类型:
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
属性。