Felix Riesterer: Forum für C#-Fragen bzw. Tipps für Objekt-Typfragen

Liebe Mitlesende,

aktuell übe ich mich unter Mono damit ab, ein Programm zu schreiben, das sowohl rein auf der Konsole, als auch mit einem Fenster (GUI) genutzt werden kann. Dazu habe ich drei Klassen definiert, eine für die reine Progammlogik (sozusagen "Backend"), eine für die Benutzerinteraktion rein auf der Konsole und eine für den Fensterbetrieb.

Wie kann ich in meinem Backend eine Referenz auf die beiden UI-Klassen ablegen, sodass ich nicht in verschiedenen Funktionen prüfen muss, ob das jetzt an das Konsolen-UI-Objekt, oder an das GUI-Objekt gehen muss, die beide diverse Methoden bieten (gleiche Methodennamen und Parameter-Listen, sozusagen eine API)? Ich möchte etwas in der Art:

[Pseudocode]~~~ class Master {
    ConsoleUI MyConsole;
    WindowUI  MyWindow;
    MasterUI  MyUI;

public void Main () {
        if (schlechteLaune) {
            // heute eine Konsole
            this.MyUI = new ConsoleUI();
        } else {
            // heute ein Fenster
            this.MyUI = new WindowUI();
        }
    }
}

  
Es ist offensichtlich, dass oben drei ganz verschiedene Datentypen definiert werden (ConsoleUI, WindowUI und MasterUI). In MasterUI hätte ich jetzt gerne ein Objekt entweder vom Typ ConsoleUI oder WindowUI, damit ich mit MasterUI.Setup() die Setup-Methode egal von der Konsolenausgabe oder dem Fenster aufrufen kann.  
  
Wie kann ich soetwas "kapseln"?  
  
Wo finde ich ein ähnlich potentes Forum wie das SELFHTML-Forum, nur eben für C#-Fragen?  
  
Liebe Grüße,  
  
Felix Riesterer.

-- 
ie:% br:> fl:| va:) ls:[ fo:) rl:| n4:? de:> ss:| ch:? js:) mo:} zu:)
  1. Tach!

    Wie kann ich in meinem Backend eine Referenz auf die beiden UI-Klassen ablegen, sodass ich nicht in verschiedenen Funktionen prüfen muss, ob das jetzt an das Konsolen-UI-Objekt, oder an das GUI-Objekt gehen muss, die beide diverse Methoden bieten (gleiche Methodennamen und Parameter-Listen, sozusagen eine API)?

    Eigentlich macht man das gar nicht so herum. Das Backend sollte die Daten in Rohform liefern und die jeweilige UI-Komponente weiß sie dann abzufragen und darzustellen. Wenn man noch weiter gehen will, landet man irgendwann bei Entwurfsmustern wie MVVM (Model-View-ViewModel).

    Außerdem geht man bei .NET anders an die Anwendungserstellung heran. Die erste Frage ist: Wird es eine Konsolenapplikation oder eine Desktop-Anwendung? Oder ist es gar nur eine Klassenbibliothek (Class Library)? Man fügt dann lieber, wenn man mit dem Visual Studio oder Sharp/Mono Develop) arbeitet, mehrere dieser Projekte zu einer Solution zusammen. In deinem Fall also eine Solution mit je einem Projrkt der genannten Typen (es gibt ja auch noch eine Menge mehr).

    dedlfix.

    1. Lieber dedlfix,

      Eigentlich macht man das gar nicht so herum. [...] Die erste Frage ist: Wird es eine Konsolenapplikation oder eine Desktop-Anwendung? Oder ist es gar nur eine Klassenbibliothek (Class Library)?

      das hilft mir weiter, denn bisher war ich ausschließlich im Dialog zwischen Browser und Web-Server zuhause. Das Schreiben von Anwendungen für die Konsole oder den Desktop ist absolutes Neuland für mich. Mir war daher nicht klar, dass man in einer *.exe-Datei nicht beide Fälle (Konsole/Fenster) abdeckt, sondern für jeden der beiden Fälle eine eigene Datei erstellt. Und dabei war ich so stolz auch mich, die Abfrage nach Command Line Parameters erfolgreich umgesetzt zu haben (-w startet bei mir jetzt die Fenster-Version)... :-)

      Man fügt dann lieber, wenn man mit dem Visual Studio oder Sharp/Mono Develop) arbeitet, mehrere dieser Projekte zu einer Solution zusammen. In deinem Fall also eine Solution mit je einem Projrkt der genannten Typen (es gibt ja auch noch eine Menge mehr).

      Momentan vermeide ich es noch, Mono-Develop einzusetzen und kompiliere auf der Kommandozeile, um dann das Programm mittels "mono file.exe" zu starten. Den Schritt hin zur IDE will ich erst machen, wenn ich die Basics wirklich verinnerlicht habe. Mir ist z.B. noch nicht klar, wie ich in Mono-Develop meine use-Anweisungen "hineinklicke" (copy&paste führt noch zu Fehlern, wohl weil ich die passenden Compiler-Optionen wie "-r:System.Windows.Forms.dll" nicht beisteuern kann) - aber das ist nur eine von mehreren Baustellen mit Mono-Develop.

      Herzlichen Dank dafür, dass Du Dir am Sonntag vor Weihnachten noch Zeit für ausführliche Antworten nimmst!

      Liebe Grüße,

      Felix Riesterer.

      --
      ie:% br:> fl:| va:) ls:[ fo:) rl:| n4:? de:> ss:| ch:? js:) mo:} zu:)
      1. Tach!

        Das Schreiben von Anwendungen für die Konsole oder den Desktop ist absolutes Neuland für mich. Mir war daher nicht klar, dass man in einer *.exe-Datei nicht beide Fälle (Konsole/Fenster) abdeckt, sondern für jeden der beiden Fälle eine eigene Datei erstellt. Und dabei war ich so stolz auch mich, die Abfrage nach Command Line Parameters erfolgreich umgesetzt zu haben (-w startet bei mir jetzt die Fenster-Version)... :-)

        Vermutlich besteht die Möglichkeit, solch eine Zwitter-Anwendung zu schreiben. Als Visual-Studio-Verwender macht man aber meist das eine oder das andere, weil es einem so von den Projektvorlagen vorbereitet wird. Du scheinst das für den Lerneffekt machen zu wollen, aber eigentlich will man soweit es geht vermeiden, Dinge zu erstellen, für deren Beschreibung man das Wörtchen "und" benötigt. Das vereinfacht die Wartung.

        Man fügt dann lieber, wenn man mit dem Visual Studio oder Sharp/Mono Develop) arbeitet, mehrere dieser Projekte zu einer Solution zusammen. In deinem Fall also eine Solution mit je einem Projekt der genannten Typen (es gibt ja auch noch eine Menge mehr).

        Da ist noch zu sagen, dass eine Solution nur ein allgemeiner Container für die gesamte zu lösende Aufgabe ist. Jedes Projekt darin erstellt entweder eine Konsolen-Anwendung oder eine GUI-Anwendung oder eine DLL.

        Momentan vermeide ich es noch, Mono-Develop einzusetzen und kompiliere auf der Kommandozeile, um dann das Programm mittels "mono file.exe" zu starten. Den Schritt hin zur IDE will ich erst machen, wenn ich die Basics wirklich verinnerlicht habe.

        Dir entgeht dabei eine ganze Menge Komfort. Ich kenne den aktuellen Entwicklungsstand von Mono Develop nicht, aber vor Jahren war ja schon Sharp Develop in seinen wesentlichen Zügen eine brauchbare Alternative zum VS. Meines Erachtens lernt man ohne IDE nur den Umgang mit den Kommanozeilen-Tools, was ich bisher noch nicht vermisst habe. Die Basics (des Programmierens, nicht der Zu-Fuß-Arbeit am CLI) sollten sich auch mit der IDE erlernen lassen.

        Mir ist z.B. noch nicht klar, wie ich in Mono-Develop meine use-Anweisungen "hineinklicke" (copy&paste führt noch zu Fehlern, wohl weil ich die passenden Compiler-Optionen wie "-r:System.Windows.Forms.dll" nicht beisteuern kann) - aber das ist nur eine von mehreren Baustellen mit Mono-Develop.

        Im Visual Studio gibt es bei den Projekten einen Abschnitt (quasi wie ein Verzeichnis) namens References. Da werden die benötigten DLLs hinzugefügt (übers Kontextmenü "Add Reference" beispielsweise). Unabhängig davon muss man natürlich noch die Namespaces mit using in die Code-Dateien einbinden.

        dedlfix.

        1. Hallo,

          Mir war daher nicht klar, dass man in einer *.exe-Datei nicht beide Fälle (Konsole/Fenster) abdeckt, sondern für jeden der beiden Fälle eine eigene Datei erstellt. Und dabei war ich so stolz auch mich, die Abfrage nach Command Line Parameters erfolgreich umgesetzt zu haben (-w startet bei mir jetzt die Fenster-Version)... :-)
          Vermutlich besteht die Möglichkeit, solch eine Zwitter-Anwendung zu schreiben.

          ja, das ist definitiv möglich. Ein- und dieselbe EXE-Datei kann je nach Aufrufkontext als Konsolenanwendung oder als GUI-Anwendung starten. Ich kenne mich aber mit .NET oder Mono überhaupt nicht aus und weiß nicht, ob diese Frameworks das unterstützen. Vermutlich eher nicht.

          Üblicherweise macht man das so, dass man in der Funktion WinMain() alle Kommandozeilen-Parameter auswertet und danach entscheidet, ob die Aufgabe des Programms ohne GUI erledigt werden kann. Wenn ja, dann ab dafür, und man muss nie CreateWindow() aufrufen, um das Hauptfenster der Anwendung zu erzeugen. Andernfalls weiter wie bei einer üblichen GUI-Anwendung.

          Ciao,
           Martin

          --
          Das einzige Problem beim Nichtstun: Man weiß nie, wann man damit fertig ist.
          Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
      2. (-w startet bei mir jetzt die Fenster-Version)... :-)

        Nicht ideal. Was passiert, wenn das Programm aus einem grafischen Dateimanager (Explorer, Konqueror/Dolphin ...) heraus gestartet wird?

        Vermutlich ist es günstiger die Umgebung zu untersuchen(*). Wird das Programm von einem Terminal aus gestartet, dann die Konsole-Version - wird es aber über eine Verknüpfung von einem grafischen Desktop aus gestartet, dann arbeite mit der grafischen Oberfläche.

        *) Frag mich nicht, wie man das in C# bewerkstelligt. Es könnte aber sowas sein.

        Jörg Reinholz

        1. Lieber Jörg Reinholz,

          (-w startet bei mir jetzt die Fenster-Version)... :-)

          Nicht ideal.

          schon klar. Später hätte ich es gerne anders herum. Wer Konsole will, der startet mit passendem Parameter, ansonsten kommt das Fenster.

          Was passiert, wenn das Programm aus einem grafischen Dateimanager (Explorer, Konqueror/Dolphin ...) heraus gestartet wird?

          Hehe, bei mir öffnet sich der Archive-Entpacker, weil ich zuletzt selbstextrahierende "pöhse" SPAM-Malware-Dateien damit testen wollte. Jetzt hat sich die Standardaktion auf diese Applikation eingeschossen. Im Kontextmenü kann ich es aber sowohl mit der Mono-Runtime, als auch mit einer Konsolenversion der Mono-Runtime öffnen.

          Vermutlich ist es günstiger die Umgebung zu untersuchen(*).

          Die verlinkte Environment.UserInteractive-Eigenschaft ist bei mir anscheinend immer "false". Ich habe das mit einer Debug-Ausgabe in eine XML-Datei geschrieben (habe auf die Schnelle den XmlWriter gefunden, reines Schreiben in eine Textdatei ist mir noch zu neu - muss ich noch lernen *g*) und gesehen, dass der Kontext völlig egal ist, die Eigenschaft ist stur "false".

          Es hätte aber ein heißer Tipp sein können. Unter WindowsXP (in einer VirtualBox) hat die EXE sofort zu einem Programmabsturz mit Option zu einem Fehlerbericht geführt... o_O

          Wird das Programm von einem Terminal aus gestartet, dann die Konsole-Version - wird es aber über eine Verknüpfung von einem grafischen Desktop aus gestartet, dann arbeite mit der grafischen Oberfläche.

          Das wäre genial obercool, aber momentan kriege ich es nicht hin. Habe auch noch keine echte Fensterausgabe, es öffnet sich bisher nur ein Fenster mit einem Klickbutton [Quit]... testweise. Dein Tipp hätte aber ein echtes Weihnachtsgeschenk werden können. Herzlichen Dank dafür!

          Liebe Grüße,

          Felix Riesterer.

          --
          ie:% br:> fl:| va:) ls:[ fo:) rl:| n4:? de:> ss:| ch:? js:) mo:} zu:)