Ik heb een hele reeks controls die erven van een user control. Deze geërfde controls hebben natuurlijk een groot aantal gemeenschappelijke velden, maar ook een aantal verschillende. Een simplistische weergave:
Base:
[MyUserControl]
• Size (Size)
• Required (bool)
• Text (string)
• Value (string)
Volgende controls erven van bovenstaande base-control:
[MyUserControl_Integer]
• Size (Size)
• Required (bool)
• Text (string)
• Value (int)
[MyUserControl_TimeSpan]
• Size (Size)
• Required (bool)
• Text (string)
• Value (TimeSpan)
[MyUserControl_String]
• Size (Size)
• Required (bool)
• Text (string)
• Value (string)
• MaxLength (int)
Zoals je kunt zien erven ze properties van de base-control, maar er zijn ook properties met een verschillend type maar dezelfde naam (Value).
Dat is allemaal geen probleem, maar nu wil ik een nieuwe user control maken waarin bovenstaande controls gebruikt worden.
Base:
Erft van bovenstaande base-control:
Maar... Het werkt niet. Alle properties uit de SpecialUserControl base class hebben totaal geen invloed op de MyUserControl_Integer control en andersom geldt hetzelfde. Het lijkt er dus op dat ik met het new keyword niet MyUserControl heb vervangen door MyUserControl_Integer, maar gewoon verborgen heb voor de afgeleide class.
Dit is een in mijn geval onbruikbaar gedrag natuurlijk. Ik wil dat de MyUserControl uit de base class vervangen wordt door de MyUserControl_Integer. Het override keyword is echter niet beschikbaar bij deze declaratie.
Hoe doe je dit wel goed?
Base:
[MyUserControl]
• Size (Size)
• Required (bool)
• Text (string)
• Value (string)
Volgende controls erven van bovenstaande base-control:
[MyUserControl_Integer]
• Size (Size)
• Required (bool)
• Text (string)
• Value (int)
[MyUserControl_TimeSpan]
• Size (Size)
• Required (bool)
• Text (string)
• Value (TimeSpan)
[MyUserControl_String]
• Size (Size)
• Required (bool)
• Text (string)
• Value (string)
• MaxLength (int)
Zoals je kunt zien erven ze properties van de base-control, maar er zijn ook properties met een verschillend type maar dezelfde naam (Value).
Dat is allemaal geen probleem, maar nu wil ik een nieuwe user control maken waarin bovenstaande controls gebruikt worden.
Base:
C#:
Ook de andere geërfde MyUserControls wil ik in een gelijkaardige SpecialUserControl opnemen. Aangezien de MyUserControls allemaal van dezelfde basis afgeleid zijn, het merendeel van de properties gelijk is, leek het me nogal stom om telkens een nieuwe SpecialUserControl aan te maken. Het lijkt me interessanter om ook deze gewoon te laten erven van SpecialUserControl:1
2
3
4
5
6
7
8
9
10
11
12
13
| public class SpecialUserControl : UserControl { protected MyUserControl myUserControl = new MyUserControl [.. code .. properties ..] [Category("Value"), DefaultValue(""), Browsable(true), Bindable(true)] public string Value { get { return this.myUserControl.Value; } set { this.myUserControl.Value = value; } } } |
Erft van bovenstaande base-control:
C#:
Dat geeft natuurlijk een aardige reductie in de te schrijven code. Door het keywoord 'new' overschrijf ik MyUserControl met MyUserControl_Integer.1
2
3
4
5
6
7
8
9
10
11
| public class SpecialUserControl_Integer : SpecialUserControl { protected new MyUserControl_Integer myUserControl = new MyUserControl_Integer [Category("Value"), DefaultValue(0), Browsable(true), Bindable(true)] public new int Value { get { return this.myUserControl.Value; } set { this.myUserControl.Value = value; } } } |
Maar... Het werkt niet. Alle properties uit de SpecialUserControl base class hebben totaal geen invloed op de MyUserControl_Integer control en andersom geldt hetzelfde. Het lijkt er dus op dat ik met het new keyword niet MyUserControl heb vervangen door MyUserControl_Integer, maar gewoon verborgen heb voor de afgeleide class.
Dit is een in mijn geval onbruikbaar gedrag natuurlijk. Ik wil dat de MyUserControl uit de base class vervangen wordt door de MyUserControl_Integer. Het override keyword is echter niet beschikbaar bij deze declaratie.
Hoe doe je dit wel goed?