Mehrfachvererbung

Vor einigen Wochen stand ich recht unerwartet vor einem trickreichen Design-Problem, bei dem es sich lohnen düfte, hier davon zu erzählen.

Für unsere im Entstehen begriffene neue .NET-basierte Programmierumgebung Triton wollte ich eine neue Control-Klasse definieren. Es ging darum, die Fokus-Steuerung, die Validierung und das Melden von Fehlern gegenüber der Standard-Klasse Form zu verbessern und zu generalisieren, und das bedeutete auch gewisse Erweiterungen bei der Funktionalität der Controls.

Also, an die Arbeit, und eine Basis-Klasse TritonControl definieren, welche die nötigen grundsätzlichen Erweiterungen und die Zusammenarbeit mit TritonForm enthält, und dann TritonTextBox, TritonCheckBox usw. davon ableiten…

Aber Moment mal: Wie soll das überhaupt gehen? Man kann der bestehenden Klasse System.Windows.Forms.TextBox ja keine neue Basis-Klasse TritonControl „unterjubeln“ bzw. sich in die Klassenhierarchie irgendwo zwischen Control und TextBox hineinzwängen. Auf der anderen Seite, gegen „oben“ in der Hierarchie, ist es zwar einfach, von TextBox eine TritonTextBox abzuleiten, aber so ergibt sich natürlich auch keine gemeinsame Basis-Klasse, sondern beim Ableiten von einem Dutzend .NET-Control-Klassen nur ein Dutzend typenmässig inkompatibler neuer Klassen, mit denen sich kein vernünftiges System bauen lässt.

Es gibt meiner Meinung nach nicht viel, was C++ der Sprache C# voraus hat, aber immerhin: In C++ wäre man jetzt hingegangen und hätte locker per Mehrfachvererbung die neue Klasse TritonTextBox eben von TextBox und TritonControl abgeleitet. Das ist so in C# nicht möglich.

Eine Analyse des Problems zeigte zwei mögliche Lösungen:

Erstens könnte man TritonControl von UserControl ableiten, und TritonTextBox wiederum von TritonControl. Ein solches Control würde dadurch zu einer Eingabemöglichkeit für einen Text, indem es zur Laufzeit dynamisch ein Child Control für sich vom richtigen Typ erzeugt, konkret eine System.Windows.Forms.TextBox, oder indem man im Designer statisch dem UserControl ein solches Child Control gibt.

Zweitens könnte man TritonTextBox von TextBox ableiten, aber zusätzlich mit einem Interface ITritonControl ausstatten.

Beim ersten Ansatz ist hauptsächlich unschön, dass man eine Menge Properties definieren muss in den von TritonControl abgeleiteten Klassen, damit deren Werte an die „inneren“, quasi an die echten Controls, weitergegeben werden können.

Beim zweiten Ansatz ist unschön, dass man das Interface mit einer ganzen Reihe von Methoden und Properties bei jedem abgeleiteten Control separat implementieren muss.

Nach einigen Überlegungen entschieden wir uns für den zweiten Ansatz. Das Implementieren des Interface ist zwar eine gewisse Fleissarbeit, aber dafür hat man sicher keinen Ärger mit dem Designer, für den eine TritonTextBox immer noch eine waschechte TextBox ist, mit der richtigen visuellen Darstellung, dem richtigen Design-Verhalten, und allen interaktiv spezifizierbaren Eigenschaften, für welche man die .NET-Controls so mag.

Veröffentlicht in Keine Kategorie. Schlagwörter: . Leave a Comment »

Schreibe einen Kommentar

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s

%d Bloggern gefällt das: