Simplify circular generic constraints in C#?

Given the following base classes:

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; }

    ...
}

Concrete implementations are as follows:

public sealed class PurchaseSystemController : PurchaseSystemControllerBase<PurchaseSystemController, PurchaseSystemViewModel> {
    ...
}

public sealed class PurchaseSystemViewModel : PurchaseSystemViewModelBase<PurchaseSystemController, PurchaseSystemViewModel> {
    ...
}

Is there a way to simplify this so that the following is possible?

public sealed class PurchaseSystemController : PurchaseSystemControllerBase<PurchaseSystemViewModel> {
    ...
}

public sealed class PurchaseSystemViewModel : PurchaseSystemViewModelBase<PurchaseSystemController> {
    ...
}
Jon Skeet
people
quotationmark

No, unfortunately not - at least, not that I'm aware of, without losing some type safety. I have a very similar set-up in my Protocol Buffers port, between the message type and its corresponding builder type.

If you'd be happy declaring the ViewModel and Controller properties with just some non-generic base types, then that's fine - but if you need the two to know the corresponding types exactly, you're left with this sort of mess.

(You might want to consider whether the ViewModel and Controller should both know about each other, mind you.)

people

See more on this question at Stackoverflow