Mehrfachvererbung

Manchmal wird man ziemlich unverhofft mit einem Problem konfrontiert, das man schon lange kannte, aber von dem man nicht ernsthaft erwartete, ihm jemals zu begegnen. So ging es mir mit der Mehrfachvererbung.

Ohne mich je genauer damit zu beschäftigen, war ich bisher der Meinung, es sei schon in Ordnung, dass viele Programmiersprachen Mehrfachvererbung nicht unterstützen, denn auf der einen Seite waren mir mögliche und vor allem sinnvolle Anwendungen nicht klar, aber auf der anderen Seite möglicher Ärger wie z.B. schwer verständliche Programme sehr wohl.

Umso mehr überrascht es mich, dass ich mir beim Design unseres neuen .NET-basierten Programmierwerkzeugs Triton jetzt genau diese Mehrfachvererbung wünsche, sie aber natürlich in C# nicht bekomme!

Worum geht es? Ich möchte die Funktionalität von Controls für Forms erweitern, notabene die von Standard-Controls wie TextBox, CheckBox, Button usw. Ich brauche z.B. Unterstützung für eine „schlaue“ Validierung von Eingabewerten, wo ich zwischen „validiert in Bezug auf den aktuellen Wert des Controls selbst“ und „validiert auch unter Berücksichtigung gegenseitiger Abhängigkeiten“ unterscheiden möchte.

So entsteht der Bedarf, eine neue Angabe ValidationState bei den Controls unterzubringen, am liebsten gleich zusammen mit einigen Methoden, welche das Validieren unterstützen.

Natürlich steht es mir frei, von allen schätzungsweise etwa 10 System.Windows.Forms.Control-Klassen, die ich brauche, neue Klassen abzuleiten und bei allen diesen eine Property ValidationState einzuführen, aber so erhalte ich natürlich 10 verschiedene Klassen mit 10 völlig unabhängigen und inkompatiblen Properties.

Ideal wäre natürlich, die Basisklasse Control selbst um eine Property ValidationState plus zugehörigen Code erweitern zu können, aber zumindest mit C# 3.0 wäre der einzige Weg hierzu eine Modifikation des Framework-Source-Codes und eine Neukompilation, was für mich natürlich nicht in Frage kommt. Auch eine abgeschwächte Variante, bei der ich Control unverändert lasse, aber eine eigene Klasse SmartValidationControl oder so quasi in den Baum der Vererbung „einfügen“ darf, hat dieselben nicht erfüllbaren technischen Voraussetzungen.

Und hier kommt jetzt die Mehrfachvererbung ins Spiel: 10 von diversen Controls abgeleitete Klassen wären in Ordnung, wenn sie ausser vom jeweiligen Control auch noch von einer zweiten Klasse SmartValidationControl ableiten dürften!

Was wäre mit 10 UserControl-Klassen mit einer gemeinsamen Basisklasse und mit dem jeweiligen eigentlichen Control als Kind? Dieser Ansatz ist natürlich möglich, artet aber aus in eine umfangreiche Fleissaufgabe, eine Menge Properties der Controls „durchzuschlaufen“, damit sie im Designer als Properties des Containers für Änderungen zur Verfügung stehen.

Schlussendlich bin ich beim folgendem Ansatz gelandet, den ich als das „geringste Übel“ ansehe: Ich leite 10 Klassen von 10 verschiedenen Controls ab, gebe aber allen diesen Klassen ein bestimmtes Interface, das ich dann eben 10 Mal implementieren muss.

Bei meinen Abklärungen über Mehrfachvererbung per Google bin ich über ein paar Seiten gestolpert, die sich vielleicht lohnen weiterzugeben:

Hier erläutert jemand aus dem C#-Team von Microsoft, dass die CLR selbst offenbar einen Weg bietet für Mehrfachvererbung, damit zumindest im Prinzip die Möglichkeit besteht, .NET-basierte Compiler zu bauen für Sprachen, welche Mehrfachvererbung umfassen.

hier hat jemand Mehrfachvererbung in C# so sehr vermisst, dass er sich eine „Simulation“ derselben ausgedacht hat, die recht trickreich mit Operatoren für implizite Typumwandlungen arbeitet. (Ich finde das Resultat insgesamt gesehen trotzdem ernüchternd.)

Und hier findet man schliesslich ein schon etwas älteres Interview mit dem „C# Compiler Program Manager“ bei Microsoft, dem man die offizielle Haltung von Microsoft zum Thema entnehmen kann.

Anhand der vielen Treffer, die Anfragen nach multiple inheritance oder auch spezifisch c# multiple inheritance in Google produzieren, kann man sehen, dass es sich offenbar um eine Sache handelt, die immer wieder aufkommt. Es wäre interessant zu wissen, ob es keine elegante Lösung des Problems geben kann, weil das Universum eben ist wie es ist, oder ob einfach noch niemand die geniale Idee gehabt hat…

Advertisements
Veröffentlicht in Keine Kategorie. Schlagwörter: , , . 4 Comments »

DataBinding und ArrayList

An sich nur eine kleine Sache, aber ich beschreibe sie trotzdem mal kurz – vielleicht hilft’s dem einen oder anderen, das Problem schneller zu lösen:

Eine DataGridView, angesetzt per DataBinding auf eine ArrayList, die in meinem Programm immer funktioniert hatte, wollte plötzlich nicht mehr: Im Grid fehlten die Kolonnen. Keine Fehlermeldung, keine Exception, einfach keine Kolonnen mehr, das DataBinding versagte.

Der Grund war ganz einfach: Vor diesem Problem war es immer so gewesen, dass zum Zeitpunkt des Erzeugens der DataGridView sich mindestens 1 Element in der ArrayList befand. Jetzt war sie leer. Da ArrayList völlig untypisiert ist, hat ohne mindestens 1 Element in der Liste der DataBinding-Mechanismus absolut nichts, womit er arbeiten kann, und das Grid bekommt keine Kolonnen. (Und dass das Grid nach dem Auftauchen des ersten Elements die Bildung von Kolonnen nachholt, ist zugegebenermassen etwas viel verlangt.)

Eine Umstellung von ArrayList auf eine typisierte List<T> behob das Problem.

Bei einer Google-Suche nach dem Problem stiess ich noch auf ein mit bisher unbekanntes Interface ITypedList, beschrieben in diesem Blog-Eintrag. Damit scheint eine Feinkontrolle des DataBinding möglich zu sein; ich muss aber zugeben, dass ich die Sache noch nicht im Detail studiert habe.

Und dann noch dies: Es muss nicht immer Google sein. Selbst in den heutigen Zeiten gibt es Leute, welche fleissig Links sammeln und Web Directories pflegen. Wenn Sie mal ein paar neue Blogs zum Thema .NET probelesen wollen, finden Sie hier gegen 100 Stück – ich denke nicht, dass Sie die alle schon kennen…

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

Forms in Visual Studio Macros

Kann man in Macros für Visual Studio Forms verwenden, oder sind diese damit überfordert? Wenn ein Macro eine Liste anzeigen will, kann es dazu eine System.Windows.Form mit einer ListBox oder sogar DataGridView verwenden, statt nur Zeilen von Text mit Hilfe einer MsgBox auszugeben oder das Output-Fenster zu verwenden?

Als ich mir kürzlich diese Frage stellte, brachte mich Google nicht weiter – ich konnte weder eine Bestätigung noch ein Dementi finden. Ich begann deshalb selbst zu experimentieren.

Erste Versuche waren nicht sehr hoffnungsvoll: Einen Designer für Forms konnte ich in der Macros IDE nicht finden. System.Windows.Forms zu importieren klappte, aber beim Aufruf der Methode Show für eine Form verhakte sich das System irgendwie. Zudem schienen alle Events in der Liste zu fehlen, die IntelliSense anzeigte für Form.

Bei einem zweiten Anlauf klärte sich allerdings einiges: ShowDialog anstelle von Show funktioniert problemlos, und betreffend Events wusste ich einfach zu wenig darüber, wie man diese genau in Visual Basic deklariert – irgendwie erstaunlich anders als in C#.

Einen Designer konnte ich auch im zweiten Anlauf nicht finden, aber das ist schliesslich kein grosses Hindernis, weil man die paar Controls, die man brauchen wird für eine Form in einem Macro, natürlich per Code produzieren kann.

Also kann ich bestätigen: Forms funktionieren in Macros für Visual Studio.

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

Compiler Bootstrapping

Beim Lesen eines Berichts über die PDC 2008 in Los Angeles stiess ich auf ein Schnippsel Information, das ich ganz interessant fand: Für die nächste Version C# 4.0 sei unter anderem geplant, den C#-Compiler (bisher in C++) in C# neu zu schreiben.

Ich habe an der ETH Zürich studiert, wo vor allem dank Niklaus Wirth eine ganze Reihe von Sprachen und zugehörigen Compilern entstanden sind (darunter Pascal, Modula-2 und Oberon), und habe den Eindruck bekommen, dass dabei stets versucht worden ist, so schnell wie möglich zu einem „self-hosting compiler“ zu kommen, d.h. zu einem Compiler, der in der Sprache geschrieben ist, die er compiliert.

Ich war deshalb überrascht zu lesen, dass in der Microsoft-Welt bis heute ein in C++ geschriebener Compiler allen C#-Code compiliert, und hatte sogar gewisse Zweifel, ob das wirklich stimmt – man soll ja nicht alles glauben, was im Internet steht…

Es ist nicht ganz einfach, eine klare Bestätigung zu finden für C++ als Implementations-Sprache des aktuellen C#-Compilers von Microsoft, aber dieser Thread hat mich schliesslich überzeugt.

Die Leute vom Mono-Projekt hatten es einfacher, weil sie den Microsoft-Compiler verwenden konnten, um ihren Compiler von Anfang an in C# zu schreiben, wie man z.B. hier nachlesen kann. Interessant ist, dass offenbar auch ein Microsoft-Mitarbeiter schon recht früh einen C#-Compiler in C# geschrieben hat (er berichtet über dieses Projekt hier), aber offenbar hat das die Compiler-„Hauptlinie“ nicht beeinflusst.

Was hat die Konkurrenz so abgeliefert in Sachen „Compiler-Bootstrapping“? Bei Java hat es nach dem allerersten, noch in C geschriebenen Compiler offenbar auch etwa 3 Jahre gedauert, bis ein in Java selbst geschriebener Compiler zur Verfügung stand, wenn man diesem Artikel glauben darf.

Wie man in der Geschichte des ersten Pascal-Compilers für die CDC 6000 nachlesen kann, wurden sogar schon Compiler von Hand übersetzt, um zu einem self-hosting compiler zu kommen. Das waren noch Zeiten…

Veröffentlicht in 1. Schlagwörter: , . 1 Comment »