Zum Inhalt springen

C# was macht "static"?


Tician

Empfohlene Beiträge

Hallo zusammen,

ich bin zwar FISI aber in letzter Zeit am Programmieren eines größeren Projekts und stoße zum wiederholten mal auf ein Wort mit dem ich recht wenig anfangen kann: static.

Ich habe gefühlte 20 verschiedene Internetseiten gelesen aber ich verstehe einfach nicht was es macht. Mir wurde gesagt das man es bei Variablen gebraucht die nicht vorgesehen sind sich zu ändern. Das wäre eine gute Konvention. Damit kann ich leben. Aber wie sieht es bei Methoden aus? Ich wollte aus meiner static Main Methode eine nicht-statische (ich kann mit "statisch" nichts anfangen sorry) Methode aufrufen und das ging nicht also have ich meine Methode statisch gemacht. Aber was verändert sich? Auf was muss ich achten?

Ich würde mich echt freuen wenn es jemand in einfachen Worten erklären kann.

Hier mal mein simples Beispiel das ohne static nicht funktioniert:

class Program
    {
        static void Main(string[] args)
        {
            Timer timer = new Timer();
            timer.Elapsed += new ElapsedEventHandler(Tick);
            timer.Interval = 60000;
            timer.Start();

            Console.ReadKey();
        }

        private static void Tick(object sender, ElapsedEventArgs e)
        {
            //get current time
            DateTime time = DateTime.Now;
            string pcZeit = time.ToString("HH:mm");

            Console.WriteLine(pcZeit); //irgendeine Ausgabe zum probieren  
        }
        
    }

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Das mit den Variablen und nicht ändern in bezug auf static ganz schnell vergessen :) ! Dieses Verhalten gibt es auch, allerdings ist das schlüsselwort dafür nicht static.

Um es kurz und prägnant zu sagen:

static:

Die Variable oder Methode gehört zu einer Klasse. Das heißt, es gibt diese Variable oder Methode nur einmal pro Klasse und kann über klassenname.methodnname() oder klassenname.variablenname genutzt werden.


kein static:

Die Variable oder Methode gehört zu einem konkreten Objekt. Das heißt, es gibt diese Variable oder Methode pro instanzierten/erstellten Objekt und kann dann über objekt.methodenname() oder objektnname.variablenname ausgeführt genutzt werden. Man könnte sich hier bspw. vorstellen, dass jedes Objekt einen namen hat der in einem String gespeichert wird. Diese variable mit der Bezeichnung "name" ist dann natürlich bei jedem Objekt sinnvollerweise anders.

Warum dein Beispiel nicht funktioniert ist Kontext bedingt. Die Methode gehört nicht zu einem konkreten Objekt, sondern wird einfach in der Klasse selbst genutzt. Deshalb muss man kennzeichnen, dass sich sich um eine Klassenmethode (static) handelt.

Das wird dir erst richtig einleuchten, wenn du dich konkret mit der Objektorientierten Programmierung auseinander gesetzt hast (wie schreibe ich Klassen für Objekte, was zeichnet diese Klassen und die darin beschrieben Variablen aus usw.).

Zusammenfassend kann man sich merken, dass man mit static kennzeichnet, dass die Methode oder Variable nicht zu einem Objekt gehört. Das macht man deswegen, weil man Klassen auf zwei weisen nutzen kann. Entweder für die Beschreibung eines Objektes, oder als reine Ansammlung von Methoden und Variablen, wie man es beispielsweise aus der prozeduralen Programmierung mit C kennt, ODER aber eben für beides gleichzeitig. Deshalb muss man hier mit Static genau differenzieren.

Bearbeitet von Uhu
Link zu diesem Kommentar
Auf anderen Seiten teilen

Super Sache, danke dir! Heißt ich muss mich nochmal genauer mit dem objektorientierten Teil auseinander setzen, aber soweit habe ich das denke ich verstanden.

http://wierbicki.de/programmierung-c/

Das sind unsere Unterlagen, wir haben schon Klassen erstellt und Methoden, sind aber nie auf "static" gestoßen (wahrscheinlich weil wir die Methoden immer in einer seperaten klasse geschrieben haben?)

Achja was benutzt man denn für Variablen die sich nicht ändern?

Bearbeitet von Tician
Link zu diesem Kommentar
Auf anderen Seiten teilen

Statics finden besonders gerne da ihren Einsatz, wo es nicht erforderlich ist, auf einem konkreten Objekt zu arbeiten.
Guten Beispiele dafür sind z.B. sogenannte Factory-Funkionen, welche dir anhand des Bauplans der Klasse dann durch eine statische Funktion ein Objekt des gleichen Typs zurück gibt. Es kann aber sein, dass ich bei dem Begriff Factory wieder in Java abgedrifftet bin, dort war es so. Das Funktionsprinzip ist jedoch das selbe, unabhängig von der Bezeichnung.

Bearbeitet von SebastianB.
Link zu diesem Kommentar
Auf anderen Seiten teilen

Hier das auch noch einmal das entsprechende Kapitel Openbook Visual C# vom Rheinwerk Verlag.

Vielleicht hilft dir das ja noch ein wenig weiter wenn es darum geht, wann man eine Variable/Methode als statisch deklariert.

vor einer Stunde schrieb Tician:

wahrscheinlich weil wir die Methoden immer in einer seperaten klasse geschrieben haben?

Was genau meinst du damit?

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 1 Stunde schrieb Tician:

Achja was benutzt man denn für Variablen die sich nicht ändern?

Wenig befriedigende Antwort: Das kommt auf den Fall an.
Man kann sich aber vorstellen, dass es Variablen gibt, die nie wieder neu initalisiert werden sollen weil ihr Inhalt immer gleich bleibt. Einige Beispiele:

- Eine Variable welche die Umsatzsteuer von 19% repräsentiert
- Eine Variable welche die Matrikelnummer eines Studenten speichert
- Eine Varable, welche die RGB-Nummer einer bestimmten Farbe speichert, z. B. rot
- Eine Variable, welche die Zahl pi speichert
- Eine Variable, die ein Ablauf- oder Erstellungsdatum eines Lebensmittels speichert



 

Bearbeitet von Uhu
Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 1 Stunde schrieb Tician:

Achja was benutzt man denn für Variablen die sich nicht ändern?

Auch hier verweise ich gerne auf das Openbook Visual C# - lese- und schreibgeschütze Eigenschaften ^^

Im Prizip ist es eine als "private" deklarierte Variable, die keinen set-Accessor besitzt.

Ansonsten gibt es auch noch ganz klassische die Konstanten für Werte, die schon bei Initialisierung fest stehen und sich auch nie ändern. Zum Beispiel so etwas wie die Kreiszahl Pi.

Bearbeitet von Rienne
Link zu diesem Kommentar
Auf anderen Seiten teilen

Zugegebenermaßen, also zu 80% komme ich mit MSDN tatsächlich nicht klar. Die restlichen 20% sind Beispiele kopieren und natürlich auf meine Bedürfnisse anpassen - aber meist stoße ich auf Probleme (entweder weil es dann nicht funktioniert oder weil ich es nicht verstehe) und ich bin ein Mensch der eigentlich alles verstehen möchte was er macht.

Zitat

Was genau meinst du damit?

Wir haben static nie gebraucht weil alle funktionen die wir in der Main-Methode aufgerufen haben in einer anderen Klasse steckten. Das meinte ich. Wenn man alle 2 Wochen mal Programmieren hat (und 1/4 dieses Unterrichts ausfallen) kann man nicht alles nach 1 Lehrjahr wissen oder?

Ich weiß das mir viele Dinge fehlen. Wir haben getter und setter-Methoden selbst in einer separaten Methode geschrieben und aufgerufen, wenn ich aber danach auf MSDN suche finde ich nur Dinge wie

int zahle = 20 {get; set};

mit sowas kann ich dann plötzlich nichts anfangen. Man sollte aber auch sagen das unser Lehrer vor 1 Jahr noch kein C# konnte, er konnte Java und hat sich daran orientiert und abgeleitet. Weswegen wir als Klasse mit ach und krach durchsetzen mussten das wir den Datentyp "string" klein schreiben dürfen.

Naja das sollte nicht in eine Lehrstunde ausarten und ich hoffe das wir den Rest an Begrifflichkeiten noch lernen oder zumindest mal anschneiden.

@Uhu

Du weißt wie man Newbie-gerecht erklärt, das ist wirklich eine super Sache, großes Lob hier an dich :) Meine Empfehlungs als Lehrer/Ausbilder hast du schonmal :P

Bearbeitet von Tician
Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 17 Stunden schrieb Tician:

Wir haben static nie gebraucht weil alle funktionen die wir in der Main-Methode aufgerufen haben in einer anderen Klasse steckten. Das meinte ich. Wenn man alle 2 Wochen mal Programmieren hat (und 1/4 dieses Unterrichts ausfallen) kann man nicht alles nach 1 Lehrjahr wissen oder?

Das sollte in der objektorientierten Programmierung ja immer der Fall sein - Methoden und Variablen sind bestandteile der Klasse zu der sie sinnvollerweise gehören. Und von den Klassen wird auch nur das, was wirklich nötig ist, nach außen sichtbar gemacht (Kapselung).

Das alles hat aber nichts mit dem Zusatz static zu tun. Normalerweise ist es ja so, dass mein seine Klasse definiert und zur Laufzeit des Programmes dann ein Objekt oder eben auch mehrere Objekte von dieser Klasse erzeugt. Statische Klassen hingegen können nicht instanziert werden und statische Methoden/Variablen sind für alle Objekte übergreifend gültig. Auch wenn das Beispiel nicht das beste ist: Zum Beispiel kann man eine statische Variable counter in der Klasse "Mitarbeiter" definieren, die jedes Mal, wenn ein Objekt der Klasse erzeugt wird um eins erhöht wird. Wenn man nun wissen möchte, wieviele Mitarbeiter bisher vorhanden sind, kann man dies mit Abruf dieser Variable tun. Dabei ist eben zu beachten, dass statische Attribute mit dem Klassennamen und nicht mit dem Namen der einzelnen Objekte aufgerufen werden. In diesem Fall dann Mitarbeiter.counter.

vor 17 Stunden schrieb Tician:

Wir haben getter und setter-Methoden selbst in einer separaten Methode geschrieben und aufgerufen, wenn ich aber danach auf MSDN suche finde ich nur Dinge wie

int zahle = 20 {get; set};

Ist bei uns nicht anders. Wenn du mit Quellcode in Berührung kommst, wirst du aber immer wieder auf solche "verkürzten" Schreibweisen treffen. Sowas muss man halt dann lernen. Im Grunde ist das dann aber eine Art Blackbox für den User und dementsprechend wird es natürlich in der Schule erst einmal anders gelehrt.

In deinem Beipiel ist das nur eine Abkürzung (die C# versteht) für:

private int _zahl;

public int zahl {

get { return _zahl;}

set{_zahl = value;}

}

Siehe auch hier wieder: get/set im C# Buch

 

Grüße Rienne ^^

Bearbeitet von Rienne
Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 2 Wochen später...
Am 29.7.2016 um 07:17 schrieb Rienne:

Zum Beispiel kann man eine statische Variable counter in der Klasse "Mitarbeiter" definieren, die jedes Mal, wenn ein Objekt der Klasse erzeugt wird um eins erhöht wird. Wenn man nun wissen möchte, wieviele Mitarbeiter bisher vorhanden sind, kann man dies mit Abruf dieser Variable tun. Dabei ist eben zu beachten, dass statische Attribute mit dem Klassennamen und nicht mit dem Namen der einzelnen Objekte aufgerufen werden. In diesem Fall dann Mitarbeiter.counter.

Das ist ein sehr schlechtes Beispiel! Das verstößt gegen das Single-Responsibility-Prinzip!
Die Mitarbeiter-Klasse hat dann plötzlich zwei Aufgaben: Zum einen repräsentiert es ein Mitarbeiter und zum anderen zählt die Klasse auch noch die Anzahl der Mitarbeiter. Die Mitarbeiter sollten in einem Repository gehalten werden und wir fragen das Repository nach der Anzahl. Schon mal es durchaus vorkommen kann, dass man temporär einen Mitarbeiter erstellen möchte, der aber wiederrum später gelöscht wird. Dadurch kann es zu schlimmen Seiteneffekte kommen, wenn die temporären Mitarbeiter-Klassen gezählt werden.

Allgemein sollte man mit static sehr vorsichtig sein. Man sollte wissen, was man da tut. 

Statische Variablen/Methoden sind schlecht zu mocken, daher sollte man sie zugunsten des Unittests vermeiden. Statische Variablen braucht man echt sehr selten und zwar so selten, dass mir nicht mal ein gescheites Beispiel einfällt. In allen Projekten, die ich inzwischen gesehen habe, wo statische Variablen benutzt worden waren, führten sie irgendwann zu massiven Problemen. Statische Methoden brauche ich eigentlich höchstens nur bei Singletons oder Factory-Methoden. Außerdem gäbe es noch die Möglichkeit Mikro-Optimierungen zu betreiben und zwar wenn ich weiß, wenn eine private Methode unabhängig vom Zustand der Klasse ist, dann deklariere ich sie als private static. Dann wird die Methode nur ein mal im Speicher gehalten.

Das Problem mit static ist, wenn sich dahinter Logik verbirgt und ein anderes Ergebnis liefert. Beispiel: DateTime.Now
Diese statische Eigenschaft gibt pro Aufruf immer ein neues DateTime zurück. Wenn man nun eine Methode testen möchte, die DateTime.Now aufruft, wird man in Schwierigkeiten kommen, einen gescheiten Unittest zu schreiben, dessen Ergebnis reproduzierbar ist, da DateTime.Now nicht reproduzierbar ist. Man fängt dann also an DateTime irgendwie zu mocken.

Am 28.7.2016 um 12:57 schrieb Uhu:

Wenig befriedigende Antwort: Das kommt auf den Fall an.
Man kann sich aber vorstellen, dass es Variablen gibt, die nie wieder neu initalisiert werden sollen weil ihr Inhalt immer gleich bleibt. Einige Beispiele:

- Eine Variable welche die Umsatzsteuer von 19% repräsentiert
- Eine Variable welche die Matrikelnummer eines Studenten speichert
- Eine Varable, welche die RGB-Nummer einer bestimmten Farbe speichert, z. B. rot
- Eine Variable, welche die Zahl pi speichert
- Eine Variable, die ein Ablauf- oder Erstellungsdatum eines Lebensmittels speichert

- Warum sollte sich der Umsatzsteuersatz nie ändern?
- Die Matrikelnummer eines Studenten gehört dem Studenten, also darf diese nicht statisch sein!
- Eine bestimmte RGB-Farbe wäre eine Konstante.
- Pi ist ebenfalls eine Konstante.
- Ablauf- und Erstellungsdatum gehören zum Lebensmittel und sind somit nicht statisch!

Diese Beispiele sind also allesamt falsch und nicht zur Nachahmung empfohlen!

Link zu diesem Kommentar
Auf anderen Seiten teilen

Es war eine Frage von mir was "static" macht und die Antworten deiner Vorredner sind zum Verständnis von jemandem der gerade in das 2. Lehrjahr kommt wirklich super. Ich schreibe momentan winzige Programme, nichts was über 50 Zeilen Code hinaus geht und das mit dem static ist mir nur aufgefallen weil ich eine Methode in meiner Main-Klasse haben wollte und Fehlermeldung war das eine nicht statische Methode nicht in einer statischen Klasse (Main wie gesagt) sein darf.

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor einer Stunde schrieb Tician:

das mit dem static ist mir nur aufgefallen weil ich eine Methode in meiner Main-Klasse haben wollte und Fehlermeldung war das eine nicht statische Methode nicht in einer statischen Klasse (Main wie gesagt) sein darf.

Main muss statisch sein, weil wie die Runtime keine Instanz der Hauptklasse anlegt, sondern lediglich DeineHauptklasse.main(args) aufruft. Du könntest aber eine weitere Klasse anlegen und in DeineHauptklasse.main eine Instanz davon erzeugen.

Dass man von statischen Methoden nur weitere statische Member aufrufen kann, ist auch klar, da man innerhalb der statischen Methode ja nicht das (nicht statische) Objekt kennt, das zu dem Aufruf gehören würde. 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Na ja, ich arbeite inzwischen seit einigen Jahren als Softwareentwickler und das, was ich schon in einigen Firmen an Code gesehen habe, geht echt unter keine Kuhhaut. Da schreiben selbst Entwickler, die 20+ Jahre Berufserfahrung haben, den allergrößten Mist an Code, den man sich nur vorstellen kann. Da werden Design Patterns auf abstruse Art- und Weisen oder sogar komplett falsch implementiert oder viele haben selbst nach 20 Jahren die Objektorientierung nicht verstanden und schreiben weiterhin spaghetticode wie in alten C-Zeiten.

An der Software, wo ich jetzt arbeite, hat man statische Klassen aus Faulheit verwendet. Damit man die Klassen nicht instanziieren braucht, hat man sie statisch gemacht (yeeaah! Man spart sich eine Zeile Code...). Hier wurde Mikro-Optimierung auf die Spitze getrieben und von solchen Klassen gibt es hunderte und diese Klassen sorgen in Unittests immer wieder für Probleme, weil z.B. die Methoden Queries an die Datenbank schicken. Der Unittest ist dann von der Datenbank abhängig. Also testet man im Unittest nicht mehr die Methoden an sich, sondern schon komplexe Programm-Strukturen auf einen Schlag. Das Problem ist nun, dass man von statischen Klassen nicht erben und somit nicht mocken kann. Martin Fowler hatte diesbezüglich mal ein Blog-Eintrag geschrieben. Sein Beispiel ist aber relativ trivial. Stell dir mal vor, du hast im Code hunderte solcher Klassen, die hunderte von Abhängigkeiten besitzen, weil man laufe der Jahren die Klassen immer um weitere Methoden ergänzt hat und die Klassen nun mehrere Tausend Zeilen beinhalten. Ist ja auch so schön einfach, einfach statische Klassen zu erweitern ...

Mir persönlich geht es auch eher darum, dass du ein gespürt dafür bekommst, wo die Probleme bei statischen Methoden/Klassen liegen und dass man schon wissen sollte, wann dieses Schlüsselwort angebracht ist und wann nicht. Nur weil man die Syntax versteht, heißt es noch lange nicht, dass man auch sauberen Code schreiben kann und das finde ich viel wichtiger als so manches andere aber das bekommt man von Firmen nicht so richtig beigebracht, weil man lieber aufgrund des Zeitdrucks lieber schmutzigen Code schreibt, der zwar jetzt schnell geschrieben werden kann und somit kostengünstig ist aber spätestens in einem halben Jahr hohe Kosten verursacht, weil der Code unwartbar ist. 

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor einer Stunde schrieb Whiz-zarD:

An der Software, wo ich jetzt arbeite, hat man statische Klassen aus Faulheit verwendet. Damit man die Klassen nicht instanziieren braucht, hat man sie statisch gemacht (yeeaah! Man spart sich eine Zeile Code...)

Das ist ein generelles Problem in der Softwareentwicklung. Häufig wird ein Problem auf eine Art gelöst, die zwar "im Moment" funktioniert, aber später für viel größere Probleme sorgt. Um bei deinem Beispiel zu bleiben: Das "Problem" (was ja eigentlich kein Problem ist, sondern so beabsichtigt ist, nur eben falsch angewendet), dass static nur static aufrufen kann wird dadurch gelöst, dass man andere Methoden statisch macht, aber sich damit andere (von dir genannte) Vorteile der OOP verbaut. 

vor einer Stunde schrieb Whiz-zarD:

Mir persönlich geht es auch eher darum, dass du ein gespürt dafür bekommst, wo die Probleme bei statischen Methoden/Klassen liegen und dass man schon wissen sollte, wann dieses Schlüsselwort angebracht ist und wann nicht. Nur weil man die Syntax versteht, heißt es noch lange nicht, dass man auch sauberen Code schreiben kann und das finde ich viel wichtiger als so manches andere

Dem stimme ich vollkommen zu. Das kommt aber auch auch mit der Zeit & Erfahrung, wenn die Projekte mal ein paar tausend Zeilen haben werden und man sich mit Architektur, Pattern usw. auseinandersetzt (was leider nicht jeder macht). 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Das es nicht beigebracht wird ist klar, ich bin kein Anwendungsentwickler und mein Ausbilder kann nur Python, ich bin also auf mich alleine gestellt sobald ich etwas programmieren soll und muss dementsprechend meinen eigenen Code ausbaden^^

Solange es tut ist alles einwandfrei, aber ich habe niemanden der mir sagen könnte welche (evtl falschen) Angewohnheiten ich mir da aneigne. Leider kann mir nicht mal unser Lehrer helfen denn der ist im Prinzip kein Lehrer und hat nur Java beherrscht bevor er von der Schule letztes Jahr angeworben wurde. Allerdings reicht es um die Grundlagen zu vermitteln :)

Aber deswegen bin ich hier im Forum, ich gebe Hilfe (sofern ich kann) und versuche Hilfe zu bekommen :)

Als Beispiel was ich mache: Wir bekommen jeden Tag einige csv-Dateien die in eine Datenbank eingelesen werden müssen.

Ziel ist einen Dienst zu bauen der sämtliche Daten (Datenbank-name, Log-In, Verzeichnisse,...) beim Start aus der Registry ließt, alle 30 sekunden nach csv-Dateien schaut, diese (falls vorhanden) entsprechend verarbeitet und in einen anderen Ordner schiebt und ein Logfile schreibt in dem eventuelle Warnungen, Errors, etc drin stehen.

Da sich ein Dienst nicht kompilieren lässt (muss installiert werden) mache ich testweise eine normale Konsolen-Aplikation. Einlesen einer vordefinierten Datei in die Datenbank funktioniert (endlich!). Der Rest kommt jetzt noch.

Bevor jetzt kommt das wir einfach ein externes, fertiges Programm benutzen könnten - ja klar könnten wir, aber dann bleibt der Lerneffekt weg und mir macht es ehrlich gesagt Spaß mich an dieser (für mich) Herausforderung zu messen.

 

Zurück zum Topic: Wenn ich das richtig verstehe gibt es kein Problem in einem 50 Zeilen Programm eine statische Methode in der Main-Klasse zu benutzen, allerdings sollte ich eine neue Klasse mit Methoden darin erstellen wenn es länger wird?

Bearbeitet von Tician
Link zu diesem Kommentar
Auf anderen Seiten teilen

vor einer Stunde schrieb Tician:

Das es nicht beigebracht wird ist klar, ich bin kein Anwendungsentwickler und mein Ausbilder kann nur Python, ich bin also auf mich alleine gestellt sobald ich etwas programmieren soll und muss dementsprechend meinen eigenen Code ausbaden^^[...]

Python ist aber auch eine objektorientierte Sprache. wenn er da die ibjektorientierte Programmierung kann, und nicht aspektorientierte oder funktionale Programmierung nur nutzt, sollte er dir zumindest schon einmal einiges an Zusammenhängen erklären können.
Besonderheiten der Sprache (Syntax oder geschweifte Klammern weglassen bei Python) ist noch einmal etwas anderes, aber eigentlich sollte jemand, der Python programmieren kann, auch mit C# klar kommen - zumindest grob. Soooo unterschiedlich sind die Programmiersprachen ja auch nicht. Gibt halt nur pro Programmiersprache meist ein paar Besonderheiten, die man beachten muss.

Bearbeitet von Crash2001
Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 1 Stunde schrieb Tician:

Zurück zum Topic: Wenn ich das richtig verstehe gibt es kein Problem in einem 50 Zeilen Programm eine statische Methode in der Main-Klasse zu benutzen, allerdings sollte ich eine neue Klasse mit Methoden darin erstellen wenn es länger wird?

Für gewöhnlich fängt man bei einer Konsolenanwendung damit an, die Main-Methode selbst zu implementieren aber hast du dir mal die Main-Methode einer WinForms- oder WPF-Anwendung angeschaut? Die besteht nur aus drei Zeilen Code. So sieht sie z.B. bei einer WPF-Anwendung aus:

public static void Main()
{
	WpfApplication1.App app = new WpfApplication1.App();
	app.InitializeComponent();
	app.Run();
}

Eine WPF-Applikation wird instanziiert, initialisiert und gestartet. Mehr passiert in der Main-Methode nicht und so sollten bestmöglich auch Konsolenanwendungen aussehen.

Wenn du nur etwas ausprobieren möchtest, kannst du gerne so viele statische Methoden benutzen, wie du möchtest. Wenn das Tool aber produktiv genutzt werden soll, dann sollte man schon darauf achten, schon von Anfang an sauber zu entwickeln, denn aus Erfahrung heraus bleibt es nicht bei diesen 50 Zeilen, sondern das Tool wird immer weiter ausgebaut und ehe man sich versieht, wurden aus diesen 50 Zeilen plötzlich 1.000 und mehr Zeilen. Dann hat man nicht nur eine Datenbank, sondern zwei unterschiedliche, die dann zwei Log-Dateien erstellen und die Datei A.csv soll in die erste Datenbank und B.csv in die zweite und vielleicht möchte man dann noch die Logging-Informationen über eine Weboberfläche darstellen, weil der Kunde kein Zugriff auf die Log-Dateien hat, etc, etc, etc...

Als weiteren Tipp geben ich dir auf den Weg, dich mit den SOLID-Prinzipien auseinanderzusetzen. Wenn man sie schon einigermaßen versteht und versucht, sich daran zu halten (oft ist es echt schwer, eine Lösung zu finden, die nicht gegen die Prinzipien verstößt), der entwickelt schon automatisch halbwegs vernünftigen Code und bitte: Schreib Unittests. ;)

 

vor einer Stunde schrieb Crash2001:

Python ist aber auch eine objektorientierte Sprache. wenn er da die ibjektorientierte Programmierung kann, und nicht aspektorientierte oder funktionale Programmierung nur nutzt, sollte er dir zumindest schon einmal einiges an Zusammenhängen erklären können.
Besonderheiten der Sprache (Syntax oder geschweifte Klammern weglassen bei Python) ist noch einmal etwas anderes, aber eigentlich sollte jemand, der Python programmieren kann, auch mit C# klar kommen - zumindest grob. Soooo unterschiedlich sind die Programmiersprachen ja auch nicht. Gibt halt nur pro Programmiersprache meist ein paar Besonderheiten, die man beachten muss.

Und wenn er es nicht kann, der Lehrer sollte es können, denn er kennt Java. Microsoft hatte sich damals bei der Entwicklung von C# viel von Java inspirieren lassen und beide Sprachen sind vom Aufbau sehr ähnlich. Ich hab früher auch hauptsächlich mit Java entwickelt. Seit einigen Jahren aber hauptsächlich mit C# und der Übergang von Java nach C# ging fließend.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Am ‎06‎.‎08‎.‎2016 um 14:30 schrieb Whiz-zarD:

- Warum sollte sich der Umsatzsteuersatz nie ändern?
- Die Matrikelnummer eines Studenten gehört dem Studenten, also darf diese nicht statisch sein!
- Eine bestimmte RGB-Farbe wäre eine Konstante.
- Pi ist ebenfalls eine Konstante.
- Ablauf- und Erstellungsdatum gehören zum Lebensmittel und sind somit nicht statisch!

Diese Beispiele sind also allesamt falsch und nicht zur Nachahmung empfohlen!

Sei mir nicht böse aber offensichtlich hast du den Kontext bei der Antwort nicht verstanden. Es ging um die Frage, warum man Variablen final machen möchte - ganz unabhängig davon ob man sie in einem statischen oder nicht statischen Kontext verwendet.

Pi, RGB, Ablauf- und Erstellungsdatum so wie die Matrikelnummer sind allesamt Konstanten - ganz unabhängig davon, ob man sie in einem statischen oder nicht statischen Kontext verwendet. Deshalb stehen die da ja auch? Das war doch die Frage! ...

Über Ust kann man sich streiten - das würde letztendlich auf das Design ankommen. Das ist aber sehr kleinlich und darum sollte es hier nicht gehen.

Wie gesagt, es ging bei der Antwort auf das Zitatt nicht um statisch oder nicht statisch, sondern nur darum ob final oder nicht. Meinen Texten hättest du entnehmen können, dass mir der Unterschied und die Verwendung von statisch oder nicht statisch durchaus geläufig ;) ... Nichts für ungut.

 

 

Bearbeitet von Uhu
Link zu diesem Kommentar
Auf anderen Seiten teilen

Bei Pi und vordefinierte RGB-Farben (RGB-Farben allerdings nur bedingt. Siehe weiter unten) bin ich dabei, dass es Konstanten sind aber Matrikelnummer und Ablauf- und Erstellungsdaten (die mehrzahl von Datum) sind keine Konstanten. Offenbar vermischst du hier final (Java) bzw. readonly (C#) Variablen mit Konstanten, aber da gibt es einen großen Unterschied:

Konstanten sind während des Kompilierens bekannt. Beim Kompilieren wird überall, wo die Konstante benutzt wird, gegen den konkreten Wert ausgetauscht. Darum können Konstanten auch nur integrierte Datentypen sein. Es läuft also erst mal ein Präprozessor, der die konkreten Werte ermittelt und diesen dann überall einfügt. Darum sollte man auch etwas vorsichtig mit Konstanten aus Drittbibliotheken sein. Wenn sich eine Konstante in einer Fremd-DLL ändern sollte, bekommt dein Code erst mal davon nichts mit, bis du dein Code neu kompilierst. Aufgrund dieser Schritte besitzt eine Konstante auch keine Variablenadresse.

Variablen hingegen werden während der Laufzeit initialisiert und sind zur Kompilierzeit nicht bekannt. Das gilt auch für final bzw. readonly Variablen. Final/Readonly Variablen werden per Initialisierung oder per Konstruktor initialisiert. 

Ob man jetzt die Matrikelnummer oder Ablauf- und Erstellungsdatum wirklich final/readonly machen möchte, ist vom Design abhängig aber ich würde das eher nicht tun. Man schränkt sich dann doch sehr extrem ein. Man müsste dann diese Werte im Konstruktor reinreichen und das sollte man bei Geschäftsobjekten nicht machen. Die XML-Deserialisierung vom .Net Framework erwartet z.B. einen parameterlosen Konstruktor. Wenn du jetzt die Studenten aus einer XML-Datei lesen möchtest, würdest du dann schon Probleme bekommen, da die Matrikelnummer readonly wäre und somit über den Konstruktor mitgegeben werden muss. Auch gängige O/R-Mapper (wie z.B. (N)Hibernate, Entitiy Framework oder Dapper) erwarten einen parameterlosen Konstruktor.  Vielleicht möchte man aber auch einfach mal einen Studenten erzeugen ohne eine Matrikelnummer. Dann wird man wieder Probleme bekommen. Man müsste dann wieder eine Factory-Methode schreiben, die einen Studenten mit einer Dummy-Matrikelnummer zurückgibt. Alles Einschränkungen, die man nicht möchte.

Wann sollte man dann also readonly verwenden?
Mir würden da spontan zwei Beispiele einfallen:

  1. z.B. die o.g. RGB-Farben. Da Konstante nur integrierte Datentypen sein dürfen, müsste man einen ganzzahligen Wert nehmen aber man besitzt vielleicht eine RGBColor-Klasse und man möchte über diese Klasse diverse Farben vordefinieren. Dafür bietet sich dann statische readonly Variablen an. Beispiel:
    public class RGBColor
    {
    	public static readonly RGBColor Black = new RGBColor { Red = 0, Green = 0, Blue = 0 };
    	public static readonly RGBColor White = new RGBColor { Red = 255, Green = 255, Blue = 255 };
    
    	public int Red { get; set; }
    	public int Green { get; set; }
    	public int Blue { get; set; }
    }
    
    

    So hätte man die Farben Schwarz und Weiß als statische readonly Variablen deklariert, die sich per Laufzeit nicht ändern und man kann per RGBColor.Black bzw. RGBColor.White darauf zugreifen.

  2. Als zweites Beispiel würde mir die Verwendung von Dependency Injection einfallen. Beispiel:

    public ClassA
    {
    	private readonly IDependency dependency;
    	
    	public ClassA(IDependency dependency)
    	{
    		if(dependency == null)
    			throw new ArgumentException();
    
    		this.dependency = dependency;
    	}
    	
    	public int DoSomething()
    	{
    		return this.dependency.DoSomething();
    	}
    }

    Ist jetzt zwar ein sehr blödes Beispiel, aber es verdeutlicht, dass ClassA von etwas abhängig ist, was das Interface IDependency implementiert und um sicher zu geben, dass es intern nicht überschrieben wird, wird es als readonly deklariert. Dies ist aber eigentlich auch nur eine Sicherheitsmaßnahme, die nicht not tut, denn in der Regel weiß ich, wie die Klasse tickt, wenn ich sie ändern sollte. Von außen habe ich ja sowieso kein Zugriff. 

Man sollte sich also im Klaren sein, was man mit dem readonly-Modifizierer erreichen möchte. Die Matrikelnummer sollte zwar nicht änderbar sein, ja aber wir kennen die Domäne nicht, wo diese Klasse verwendet wird und ggf. ist die readonly-Einschränkung zu viel für den Verbraucher, sodass diese Klasse für ihn unbrauchbar wird. Siehe die Deserialisierung oder es kann ja durchaus möglich sein, dass man die Matrikelnummer mal doch ändern möchte und dann müsste man einen hohen Aufwand betreiben um so etwas realisieren zu können, wenn man nicht in der Lage ist, die Klasse ändern zu dürfen, weil sie vielleicht in einer Drittbibliothek steckt.

Link zu diesem Kommentar
Auf anderen Seiten teilen

In meinen Augen darf die Martikelnummer nicht geändert werden - sie ist eindeutig und wird auch nach dem Studium nicht neu vergeben. Aber wie du schon sagst, es ist sicherlich Design abhängig. Darum sollte es aber auch nicht gehen. Es ging um einfache Beispiele, wann Variablen ggf. ihren Wert beibehalten sollen. Das ganze Fachwissen das du jetzt Aufgrund deiner Erfahrung ausschreibst, hilft dem Threadersteller recht wenig. Es geht ums Prinzip, da der Threadersteller keine Vorstellung davon hatte, dass es Variablen geben kann, die man nicht ändern möchte. Nicht mehr und nicht weniger. Belassen wir es dabei.

Bearbeitet von Uhu
Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich möchte nur noch kurz anmerken, dass auch bei (abstrakten) "Helper-Klassen" gerne statische Methoden verwendet werden. Ein Beispiel hierzu wäre die System.Math-Klasse.

Im Grunde kann man davon ausgehen, dass Methoden, die nicht über Seiteneffekte mit Membern "kommunizieren"(ausgenommen statische Member), als statisch definiert werden können.

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 7 Stunden schrieb Uhu:

In meinen Augen darf die Martikelnummer nicht geändert werden - sie ist eindeutig und wird auch nach dem Studium nicht neu vergeben.

Auf meiner damaligen Schule waren die Matrikelnummer aus Einfachheit nur vierstellig. D.h. ab den 9000. Schüler fingen sie wieder bei Nummer 1000 an. Matrikelnummern müssen also nicht auf alle Zeit eindeutig sein. Wozu auch? Nach der Exmatrikulation steht die Nummer wieder zur Verfügung. Eine Matrikelnummer ist etwas fachliches und nicht technisches, wie eine eindeutige ID, die für alle Zeit eindeutig sein muss.

Matrikelnummern können in alle Zeit eindeutig sein, ja aber das hat das nicht Geschäftsobjekt zu entscheiden, sondern die Geschäftslogik; Sprich also die Validierung. Gängige O/R-Mapper haben eine integrierte Validierung, die man nach belieben konfigurieren kann. Darunter auch, dass beim Persistieren bestimmte Eigenschaften nicht geändert werden dürfen.

vor 7 Stunden schrieb Uhu:

Das ganze Fachwissen das du jetzt Aufgrund deiner Erfahrung ausschreibst, hilft dem Threadersteller recht wenig. Es geht ums Prinzip, da der Threadersteller keine Vorstellung davon hatte, dass es Variablen geben kann, die man nicht ändern möchte. Nicht mehr und nicht weniger. Belassen wir es dabei.

Es geht mir in erster Linie darum vor Anfängerfehler zu bewahren, da man z.B. mit der Matrikelnummer eine falsche Vorstellung bekommt, wann readonly angebracht ist und wenn man es einem Anfänger erklärt, warum dann nicht gleich richtig?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...