[C#] Virtueller Konstruktor
-
Ahoi ... ich bin noch etwas frisch in C#, daher mal ne Frage ...
Ich möchte eine kleine Klassenhierache basteln. Genau genommen werden von einer abstrakten Basisklasse Spezialisierungen abgeleitet, bei den Spezialisierungen findet keine weitere Ableitung statt.Mit einem virtuellen Konstruktor in der Basisklasse wollte ich sicherstellen, dass die Signaturen alle Konstruktoren der Spezialisierungen identisch sind. Das verweigert mir allerdeings der Compiler ... was kann ich tun bzw. welche Alternativen hätte ich?
Danke im Voraus!
-
virtuelle Konstrutkoren ergibt kein Sinn.
Wenn du die signaturen identisch machen willst, dann mach sie doch identisch und ruf den base(...) ctor bei dem jeweiligen spezialisierten objekt auf.
-
was kann ich tun bzw. welche Alternativen hätte ich?
Z.B. Prototype Pattern anwenden.
http://en.wikipedia.org/wiki/Prototype_pattern
-
Firefighter schrieb:
virtuelle Konstrutkoren ergibt kein Sinn.
Und ob. Allerdings ist die Unterstützung von Klassenpolymorphie Voraussetzung, und die CLR bietet das meines Wissens nicht.
-
Soweit ich weiß, bietet das nichtmal C++ an,wenn doch dann bitte nen Link wo die Sinnhaftigkeit erklärt wird.
-
Firefighter schrieb:
Soweit ich weiß, bietet das nichtmal C++ an
Nein, tut es auch nicht.
-
Ok du sagtest "und ob". Ich kann mir keinen reim drauf machen warum es sinn machen sollte, kannst du mir kurz erklären was du dir darunter vorstellst?
-
Einfaches Beispiel aus der VCL, leicht abgewandelt:
type TGraphicClass = class of TGraphic; TGraphic = class class function FindClass (FileExt: String): TGraphicClass; class procedure RegisterClass (AClass: TGraphicClass); class function SupportsFileFormat (FileExtension: String): Boolean; virtual; abstract; constructor CreateFromFile (FileName: String); virtual; abstract; end; TBitmap = class (TGraphic) class function SupportsFileFormat (FileExtension: String): Boolean; override; constructor CreateFromFile (FileName: String); override; end; class function TBitmap.SupportsFileFormat (FileExtension: String): Boolean; begin Result := (FileExtension = '.bmp') or (FileExtension = '.dib'); end; initialization TGraphic.RegisterClass (TBitmap); ... Result := TGraphic.FindClass (ExtractFileExt (FileName)).CreateFromFile (FileName);
-
Eventuell verstehe ich da etwas falsch ... oder ihr ^^
Also die abstrakte Basisklasse ist ja deshalb abstrakt, weil sie nur die Vorlage darstellt, welche Operationen Ableitungen später implementieren sollen. Da nicht unbedingt alle Ableitungen durch mich geschrieben werden könnten, wollte ich über einen virtuellen Konstruktor sicherstellen, dass trotzdem auch alle Konstruktoren die gleiche Signatur besitzen. Wie kann ich das erreichen wenn es damit eben nicht geht?
MfG
-
Warum willst Du die Signatur des Konstruktors vorgeben?
Simon
-
Du könntest eine Fabrikmethode verwenden:
http://de.wikipedia.org/wiki/Factory_Method
-
ctor schrieb:
Eventuell verstehe ich da etwas falsch ... oder ihr ^^
Also die abstrakte Basisklasse ist ja deshalb abstrakt, weil sie nur die Vorlage darstellt, welche Operationen Ableitungen später implementieren sollen. Da nicht unbedingt alle Ableitungen durch mich geschrieben werden könnten, wollte ich über einen virtuellen Konstruktor sicherstellen, dass trotzdem auch alle Konstruktoren die gleiche Signatur besitzen. Wie kann ich das erreichen wenn es damit eben nicht geht?
MfG
Garnicht.
Und wozu bitte soll das auch gut sein?
Wenn jemand nur Konstruktoren mit anderen Signaturen implementiert, dann muss man die Klasse eben anders konstruieren. Und? Egal. Eben.
-
Ich würde darauf tippen das der Fragesteller unbekannte Objekte konstruieren möchte und deswegen auf die Signatur besteht. (In dem Falle:
Du könntest eine Fabrikmethode verwenden:
http://de.wikipedia.org/wiki/Factory_Method)
-
Das wäre möglich. Bloss dann hat er seine Frage ungenau formuliert. Sein Anliegen/Vorhaben/... ungenügend geschildert.
@ctor:
Also die abstrakte Basisklasse ist ja deshalb abstrakt, weil sie nur die Vorlage darstellt, welche Operationen Ableitungen später implementieren sollen.
Wenn T eine Klasse ist, dann ist "new T(a, b, c)" keine Operation "auf T", sondern eine Operation "auf nichts".
Das Factory-Pattern das vorgeschlagen wurde wandelt "new T(a, b, c)" dann zu "CreateT(a, b, c)" um, und das ist dann eine Operation auf der Factory.
Du definierst also ein TFactory Interface, welches eine CreateT Funktion enthält, und das Problem ist gegessen. Der ctor von T ist zu einer normalen Funktion von TFactory geworden.
Sprachen die virtuelle Konstruktoren unterstützen nehmen einem hier zugegebenermassen einen Teil der Arbeit ab, aber damit erreicht man nichts, was man nicht relativ einfach mit C#/Java/C++ nachbilden könnte.
-
Ahoi ...
Ja das Factorypattern hatte ich auch schon in Erwägung gezogen, ist ja gewissermaßen die einzige Alternative. Aber wie gesagt, bin recht frisch in C# und vieleicht hätte es da ja noch einen anderen Weg gegeben.
Das viele von euch die sinnhaftigkeit eines virtuellen Konstruktors anzweifeln, überrascht mich ein wenig. Audacia hat ein schönes Beispiel gegeben, grad die VCL macht davon sehr oft gebrauch.
Falls ich mein Problem schlecht formuliert hab ... mhmm vieleicht tu ich mir da manchmal etwas schwer
Im Grunde gehts darum:
- es gibt verschiedene Datenquellen, die Zugriffsklassen benötigen
- die Basisklasse dient als Vorlage für konkrete Implementierungen
- die Controllerklasse sollte ohne großen Aufwand Instanzen der Zugriffklassen erzeugen können, daher wollte ich auch die Signatur des Konstruktors vorgebenOk, dann nutze ich einfach das Factorypattern ... danke an alle!
-
BTW, es ist günstiger die abstrakte Klasse nicht als "Zwangsimplementierung" zu verwenden, da du so die Implementoren sehr fest miteinander verkettest. Vielleicht gibt es mal eine Datenquelle die sich so sehr von den vorhandenen unterscheidet das das Implementieren der abstrakten Klasse für dieses Datenquellen-Objekt eher hinderlich ist. Vielleicht ist es besser ein Interface als Vereinbarung zu verwenden, die Klassen können ja immer noch von einer abstrakten Klasse erben um Code-duplikation zu vermeiden.
-
ctor schrieb:
- die Controllerklasse sollte ohne großen Aufwand Instanzen der Zugriffklassen erzeugen können, daher wollte ich auch die Signatur des Konstruktors vorgeben
Das vorschreiben einer ctor Signatur alleine hätte dir aber auch nix gebracht.
Angenommen irgendwer hätte dir jetzt gesagt: das geht so und so.
Wie hättest du dann ohne Factory die Objekte erzeugen wollen?