tagchen
habe einen stack von UserControls, nämlich
UserControl1:UserControl, UserControl2:UserControl, ..
Meine UserControls haben alle gleiche Methodensignaturen und etwa 4 Member vom gleichen typ sind immer nötig.
mein erster, liebster Ansatz war
public abstract class GenericUserControl:UserControl
{..}
und
public partial class UserControl1:GenericUserControl
( vorher:
public partial class UserControl1:UserControl
)
-> d.h ich ha ne "Zwischenschicht" eingebaut. Jetzt reklamiert der Designer da er mit der abstrakten Klasse keine Oberfläche zeichnen kann. Dabei würde ja der base() Konstruktor von UserControl reichen. Kann man das steuern?
Falls nein, gibts noch den Weg über Interface, wobei ich aber dann die 4 Member glichen Typs jedesmal ins UserControlxy packen muss... da ich nur Methoden in der Schnittstelle hab.
also:
public partial class UserControl1:UserControl, IUserControl{}
public class GenericUserControl:UserControl
{
virtual void Foo(){ MessageBox.Show("Dummy Foo"); // muss impl sein, kann überschrieben werden
}
tja, was ist nun gutes Design?
Hallo mathias_f,
die frage ist warum möchtest du die klasse dazwischen noch abstrakt machen ?
Ich würde da virtuelle Methoden verwenden und ggf. überschreiben.
Wenn du möchtest das gewisse methoden implementiert werden müssen, nimmst du halt bei den Erbenden noch dein(e) Interface(s) hinzu.
André
tja, was ist nun gutes Design?
Keine Variante davon:
Wenn du Logik und Präsentation trennst, kannst du die entsprechenden Methoden mit ziemlicher Sicherheit in den Klassen unterbringen, die für die Logik zuständig sind.
Und hier kannst du dann wunderbar abstrakte Klassen etc. verwenden.
Sind die Methoden tatsächlich präsentationsspezifisch, kannst du sie in eine Klasse auslagern (bzw. evtl. in mehrere) und diese Klasse dann jeweils in den Controls nutzen.
Hallo,
das von winSharp93 Gesagte kann ich nur unterstützen!
Hier mal einige Überlegen, die bei der Entscheidung Basisklasse mit abstrakten/virtuellen Methoden vs. Interfaces helfen:
Wenn Methoden eine gemeinsame Implemetierung für alle erbenden Klassen aufweisen sollen, dann eignen sich normale Methoden in einer Basisklasse.
Wenn Methoden eine gemeinsame Implemetierung für die meisten erbenden Klassen aufweisen sollen, die aber vereinzelt abweichen kann, dann eignen sich virtuelle Methoden in einer Basisklasse.
Wenn die Implementierung größtenteils voneinander abweichen (so daß sowieso jede Klasse eine eigene Implementierung bekommt), eignen sich abstrakte Methoden oder auch Interfaces.
Du kannst aber auch beides mischen, und die Basisklasse zusätzlich ein Interface implementieren lassen, oder noch abstrakte Methoden einbauen, die dann ebenfalls von den erbenden Klassen implementiert werden müssen.
Ob das nötig ist, hängt maßgeblich davon ab, wo und wie die Instanzen später verwendet werden sollen. Interfaces eignen sich z.B. dazu, nur einen Teil der Funktionalität anderen Klassen/Methoden per Übergabe zur Verfügung zu stellen.
Gruß, MarsStein
EDIT: das sind natürlich nur ein paar Grundüberlegungen, ohne Anspruch auf Vollständigkeit
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
die klasse dazwischen noch abstrakt machen ?
Ich würde da virtuelle Methoden verwenden und ggf. überschreiben.
einfach weil es beim dem vererbenden UserControl um kein "echtes", voll funktionsfähiges handelt und somit davon keine instanzen gemacht werden sollen (ausser der desinger wills)
Mit normaler Klasse und virtuellen Methoden gehts wie beschrieben schon mal.
danke für die beiträge
Wenn du Logik und Präsentation trennst, kannst du die entsprechenden Methoden mit ziemlicher Sicherheit in den Klassen unterbringen, die für die Logik zuständig sind.
Und hier kannst du dann wunderbar abstrakte Klassen etc. verwenden.
hmm, das klingt jetzt stark nach WPF, mache aber WinForms und "Auftrennen" würd ich auch gerne, klingt aber stark nach Mehrfachvererbung (!).
class UserControl1:UserControl, UserControlLogic{}
oder wie hast du das gedacht?
Hallo mathias_f,
du versuchst krampfhaft alles zu vererben - das ist der falsche Weg. Meistens reicht eine einfache Komposition (also einfach als Member der Klasse anlegen) völlig aus.
Vererbung ist nur dann sinnvoll, wenn du wirklich sagen kannst: "ein A ist auch ein B".
Du brauchst also nur die Logik als Member zu verwenden:
class UserControl1 : UserControl
{
private UserControlLogic logic = new UserControlLogic();
}
hmm, das klingt jetzt stark nach WPF, mache aber WinForms und "Auftrennen" würd ich auch gerne
Schaue dir einmal MVP (Model-View-Presenter) an - eine solche "Auftrennung" ist nichts WPF-Spezifisches.