Laden...

Soll eine statische Variable mit oder ohne "get;" und "set;" verwendet werden?

Erstellt von PierreDole vor 3 Jahren Letzter Beitrag vor 3 Jahren 1.432 Views
P
PierreDole Themenstarter:in
74 Beiträge seit 2017
vor 3 Jahren
Soll eine statische Variable mit oder ohne "get;" und "set;" verwendet werden?

Moin,
bin gerade am überlegen, wie ich eine static Variable handhabe.

Zum einen kann ich sie gleich definieren:


public static class StaticClass
    {
        public static int myStaticInt = 0;
    }

oder ich arbeite mit get und set und setze sie beim Start in MainWindow():


public static class StaticClass
    {
        public static int myStaticInt { get; set; }
    }

public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            StaticClass.myStaticInt = 0;
        }
    }

Für den weiteren Verlauf des Programms ist die Art, wie ich es mache, egal, da ich sie immer nur noch mit StaticClass.myStaticInt aufrufen bzw mit StaticClass.myStaticInt = Wert setzen werde.
Geht es hier mehr als nur um Programmierästhetik? Und welche Form ist die "richtige"?

16.835 Beiträge seit 2008
vor 3 Jahren

Erklär mal welchen Zweck Du verfolgst.
Vermutlich gibt es was viel besseres als static dafür.

Für Settings gibts zB das Microsoft Configuration Framework, das auch sauber über Dependency Injection und Live Refresh nutzbar ist.
Statische Klassen sind nicht dazu da, dass Du darüber Klassen kommunizierst. Damit machst Du Deine Anwendung quasi untestbar.

P
PierreDole Themenstarter:in
74 Beiträge seit 2017
vor 3 Jahren

Ich bekomme ich eine Liste mit Servernachrichten. Jede neue Nachricht wird am Ende der Liste eingefügt und ich bekomme immer nur die volle Liste. Relevant sind aber immer nur die neuen Nachrichten, die noch nicht überprüft wurden.
Jetzt wollte ich eine Klasse schreiben, mit der ich mir den Zugriff vereinfache und überlege, wie ich das mache. Da ich von mehreren Stellen des Programms auf die Nachrichten zugreife, brauche ich einen Zwischenspeicher für den letzten aufgerufenen Index, quasi den letzten List.Count. Das Naheliegendste erschien mir eine static Variable.

T
2.224 Beiträge seit 2008
vor 3 Jahren

Richt sehr nach globaler Variable.
Bitte nie, auch nicht bei static Klassen, einfach die Felder ohne getter/setter offen legen.
Auch wenn diese nur die auto getter/setter vorhanden sind, hast du damit durch einen setter immer einen Zugriffsschutz der z.B. ungültige Werte abfangen und bei bestimmten Pattern auch zusätzliche Aufgaben hat!

Ansonsten spricht doch nichts dagegen, die Information in einer Datei/lokalen Datenbank abzulegen.
Da die Information dann auch persistiert ist, kannst du auch über einen Neustart der Anwendung hinweg die richtigen Werte anzeigen.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

16.835 Beiträge seit 2008
vor 3 Jahren

Was Du da hast ist im Prinzip ein Paradebeispiel, wofür man static nicht verwenden sollte.

Du verschaffst Dir damit eine sehr hohe Abhängigkeit, machst den Code am Ende untestbar und hast viel Potential für Race Conditions.
Du verfolgst hier im Grunde nichts anderes als einen simplen Producer Consumer Pattern.
Reactive Extensions ist die derzeit modernste und zeitgleich in diesem Fall auch wohl der effizienteste Weg dieser Problemlösung.

Mit Rx erstellst Du ein Observable, auf der einen Seite kippst Du die Nachrichten rein; auf der anderen Seite subscribst Du sie.
Das ist sauber und modular, super via Dependency Injection - und Du bleibst auch [Artikel] Drei-Schichten-Architektur treu.

101 Rx Samples in C#

Den Aspekt mit der Datenbank würde ich nicht in Betracht ziehen; das wird sehr wahrscheinlich hier mit Kanonen auf Spatzen geschossen sein, wenn das überhaupt ein adäquater Weg wäre.
Nicht für alles braucht man direkt eine Datenbank oder ein Message Broker...

Auch teile ich die Aussage mit dem statischen Feld nicht.
Es gibt durchaus relevante und legitime Anwendungsfälle dafür, auch wenn das hier nicht der Fall ist.

P
PierreDole Themenstarter:in
74 Beiträge seit 2017
vor 3 Jahren

Danke für eure Antworten. Jetzt habe ich noch mehr Fragen. 😃

Habe mir Rx angeschaut aber auch das 3-Schichten-Modell und denke, ich sollte zuerst meinen Code strukturieren bevor ich mich Rx zuwende.

Als ich Artikel zum 3-Schichten-Modell mit ihren kleinen Beispiel-Codes gelesen habe, dachte ich mir, es sei im Grunde einfach. Doch wenn ich dieses Modell auf meinen Code, bzw meine Gedankengänge übertragen möchte, wird es plötzlich kompliziert.

Die nachfolgende Situation/Frage ist exemplarisch dafür, warum ich auf globale Variablen zurückgreife:

Sagen wir, die Daten-Schicht greift auf einen SQL-Server im Netz zu. Dieser geht down und ist nicht erreichbar. Jetzt soll eine Nachricht in der GUI erscheinen a la "Daten-Server down!". Wie kommt diese Nachricht durch die Schichten zur GUI? Oder ich möchte, daß gewisse Vorgänge in der Logik-Schicht eine Nachricht ausgeben. Wie macht man das?
Wenn ich das 3-Schichten-Modell richtig verstanden habe, hat es die GUI-Schicht nicht zu interessieren wie und was die Logik-Schicht macht. Die GUI-Schicht erwartet nur ein Ergebnis. Genauso sieht es mit der Beziehung zwischen der Logik- und der Data-Schicht aus. Die Logik-Schicht weiß nicht woher die Data-Schicht ihr Daten bekommt. Wie bekomme ich also die Fehlermeldung (bzw einen Fehlercode) durch die Klassen zur GUI-Schicht?
Als einziges fällt mir nur ein, eine static Klasse zu schreiben, nennen wir sie "Console", ihr beim Start die Instanz des Labels, in dem die Nachrichten angezeigt werden, zu übergeben, und mittels Console.ShowMessage("Ging nicht/Ging doch/ etc.") von überall im Code darauf zuzugreifen. Damit kennt der gesamte Code die GUI-Schicht, bzw ein Element der GUI, was nicht sein soll (wenn ich es richtig verstanden habe). Wie löst man das?

16.835 Beiträge seit 2008
vor 3 Jahren

"Globale Variablen" sind grundlegende Designfehler in Software Architekturen.

Wie kommt diese Nachricht durch die Schichten zur GUI?

Die entsprechende DAL-Methode wirft eine Exception, die Du in der UI fängst.

Wie macht man das?

Exceptions.

Wie bekomme ich also die Fehlermeldung (bzw einen Fehlercode) durch die Klassen zur GUI-Schicht?

Exceptions.

Wie löst man das?

Exceptions 😃

Handling and throwing exceptions in .NET

Statische Klassen haben in C# durchaus einen Sinn - jedoch nicht für Deinen Anwendungsfall hier.
Informationswege gehen immer neutral durch die Schichten.

Kennt Deine Logik-Schickt die UI, dann hast Du einen klassichen Designfehler im Sinne von Technologieabhängigkeiten.
Das Problem: hast Du so einen Fehler ein mal drin kommst Du ganz selten ohne generellen Code-Umbau wieder sauber raus.

G
16 Beiträge seit 2019
vor 3 Jahren

Gerade das hochbubbeln von Exceptions muss man mal verstehen. Ich finde dieses Video dazu sehr verständlich, ist jedoch auf Englisch aber ein sehr einfaches verständliches Englisch
Exceptions Handling by Tim Corey

Wenn es um Architektur im Allgemeinen und/oder Softwarequalität geht dann ist dieser Trainer ein sehr guter Tipp. Ist auf Deutsch und aktuell gibt es jeden Tag auch so eine Art Developers Daily mit diversen Themen rund um die Entwicklung
Auch seine Codebeispiele sind sehr gut erklärt, reinschauen lohnt sich definitiv
David Tielke

P
PierreDole Themenstarter:in
74 Beiträge seit 2017
vor 3 Jahren

Haha, Exceptions! Da war ja mal was. 😄 Die hatte ich überhaupt nicht auf dem Radar (obwohl ich ständig welche um die Ohren geworfen bekomme). Ok, notiert!

Das löst mein Problem aber noch nicht vollständig, da Exceptions nur für Fehler und andere Ausnahmen gedacht sind. Was ist aber mit Statusmeldungen? Ich schreibe die gerade auf Events um, aber irgendwie gefällt mir das auch noch nicht ganz. Ist es üblich ein Event durch ein anderes Event zu invoken? Anders komme ich nicht durch die Klassen an die GUI.

Die Youtube-Kanäle sehen sehr interessant aus, aber leider brauche ich alles, aufgrund meines Gehörs, in Textform.

16.835 Beiträge seit 2008
vor 3 Jahren

Was ist aber mit Statusmeldungen?

Statusmeldungen sind Ereignisse, unabhängig ob Du diese nachher in einer UI anzeigst oder nicht.
Ob Du in der Verarbeitung einer Ereignisses nachher eine Exception wirfst oder etwas in der UI anzeigst, das ist dem Ereignis egal.
Die entsprechende Anzeige ist ja nur die visuelle Verarbeitung.

Ja, Events sind hier der richtige Weg.

Ist es üblich ein Event durch ein anderes Event zu invoken?

Üblich ist relativ; ungewöhnlich ist es nicht.

Modern würde man es über Subscriptions machen, sodass sich Events nicht gegenseitig kennen müssen und so die Abhängigkeit entfällt.
=> ReactiveX - Observable

Im Groben fällt das unter dem Paradigma von Event Sourcing