I have a special wizard system, which so far has been quite suitable. For most wizards, pages can be built in a fairly general way, so only one class implements these types of pages. However, some of them must be specially designed, therefore, for these types of pages there is an abstract base class. Due to some drawbacks of the VS designer, the page itself cannot be a user interface control element, nor can it be an abstract class with common parameters (which exist for free programming). Thus, one of the options that I used is to implement the page in two classes: one for the UI (which comes from UserControl and can be developed), and the other for the page.The page contains an instance of the user interface control and inserts it for display. Not optimal, but it works.
Now a problem arises from this setting: there is a hard link between the UI management class and the page class. This is usually not a problem, except that data can be obtained to create specialized versions of the pages. Thus, derived control classes and pages are also closely related to themselves. Therefore, when I have member variables, properties and methods for control classes and pages that are introduced for the control or class, respectively (i.e. the Control class will have a propertyPage, which points to the page into which the control is embedded), we are faced with a big problem with derived classes. Each derived class must somehow change the type of these members. What I was thinking about doing included a parameter of a generic type that allows us to typify these members:
public class BaseControl<TControl, TPage>
where TPage : BasePage<TPage, TControl>
where TControl : BaseControl<TControl, TPage> {
public TPage Page { get { ... } set { ... } }
...
}
public class BasePage<TPage, TControl>
where TPage : BasePage<TPage, TControl>
where TControl : BaseControl<TControl, TPage> {
public TControl Control { get { ... } set { ... }
...
}
public class DerivedControl<TControl, TPage> : BaseControl<TControl, TPage>
where TControl : DerivedControl<TControl, TPage>
where TPage : DerivedPage<TPage, TControl> { }
public class DerivedPage<TPage, TControl> : BasePage<TPage, TControl>
where TControl : DerivedControl<TControl, TPage>
where TPage : DerivedPage<TPage, TControl> { }
Obviously, this is a type of garbage like C ++, which I would like to avoid. In addition to ugliness, it creates a real problem when you need to create closed "leaf" classes to solve the problem of infinite recursion that CRTP brings us.
. , , . ( , --, ). , abstract . ( , , , ).
, , . , , , . -, , - , ?