
Whiz-zarD
Mitglieder-
Gesamte Inhalte
2083 -
Benutzer seit
-
Letzter Besuch
-
Tagessiege
51
Inhaltstyp
Profile
Forum
Downloads
Kalender
Blogs
Shop
Alle Inhalte von Whiz-zarD
-
Synchronisation einer Oracle DB mit einer MySQL DB
Whiz-zarD antwortete auf gluexxpirat's Thema in Abschlussprojekte
Warum den Umweg über mysql? Warum greifst du nicht direkt die Daten von der Oracle Datenbank ab? -
Vorstellungsgespräch wegen Wetterlage verschoben - negatives Bild?
Whiz-zarD antwortete auf wisdomsoz's Thema in Ausbildung im IT-Bereich
Termine können immer kurzfristig platzen. Egal von welcher Seite aus. Ich denke mal, jeder wird es mal erlebt haben, dass eine Person aus der Firma, die eigentlich am Gespräch teilnehmen wollte, nicht konnte. So ist es nun mal und ich finde es auch nicht schlimm, wenn man rechtzeitig bescheid sagt. Bei Bewerbern um einen Ausbildungsplatz muss man eben damit rechnen, dass sie noch recht jung sind und keinen Führerschein besitzen und daher auf öffentliche Verkehrsmittel angewiesen sind. That's life ... -
Ist doch ganz gleichgültig, ob es ein Aushilfslehrer ist, oder nicht. Er soll die Schüler vernünftig unterrichten. Auch handelt es sich hier nicht um eine 7. Klasse, wo es scheißegal ist, ob sie Objektorientierung verstehen oder nicht, sondern es geht um Azubis, dies dies in ihrem Berufsleben brauchen. Der Lehrer springt aber von den Klassen zu Arrays, ohne überhaupt mal zu erklären, wozu überhaupt Klassen gedacht sind. Er verschiebt den Code nur von einer Klasse zur nächsten ... Ja, wow. Dafür brauche ich kein C#, sondern kann dafür auch eine prozedurale Sprache, wie z.B. Pascal, nehmen. Es hat doch keinen Sinn, eine Objektorientierte Sprache zu wählen, wenn man den Azubis nicht mal erklärt, was Objektorientierung überhaupt ist. Er springt auch mit den Themen kreuz und quer ohne einen roten Faden zu besitzen. z.B. von den erwähnten Klassen zu Arrays oder von der for-Schleife zu Modulo und von Modulo zur Random-Klasse. Was ist mit den anderen Arten von Schleifen? Von WinForms zu Boolesche Algebra. Was ist das denn für ein Unterricht? Man sieht ja, was dabei rauskommt, nämlich nichts ... Wenn man aber bei den Themen von Pontius zu Pilatus springt, nimmt man die schwachen Schüler nicht mit. Im Gegenteil. Sie verlieren schneller den Überblick, weil sie den Themen einfach nicht folgen können. Im Unterricht sollte ein roter Faden zu sehen sein und der fehlt hier komplett. Es wird irgendwie alles nur kurz angerissen ohne näher darauf einzugehen. Sorry, aber mit so einem Wissensstand kann man noch keine Programme mit C# schreiben, da einfach das komplette Wissen über Objektorientierung fehlt. Wenn man schon die Objektorientierung weglassen möchte, was bei Anfängern vielleicht durchaus verständlich ist, dann sollte man auch meiner Meinung nicht mit einer OO-Sprache anfangen, weil es sonst für Verwirrung sorgt. Bei meiner Assistenten-Ausbildung wurde auch mit Pascal anfangen aber Pascal ist heute wohl nicht mehr "fancy" genug. Meine damalige Ausbildung habe ich 2008 begonnen und 2011 abgeschlossen. Das Problem sieht man schon in diesem Video von ihm. Er beschreibt den Konstruktor falsch. Er implementiert einen Konstruktor, nur weil er Quelltext sparen möchte. Das ist aber nicht der Sinn und Zweck eines Konstruktors. Der Konstruktor ist dafür da, um ein Objekt zu initialisieren. Parameter reicht man dann in ein Konstruktor rein, wenn das Objekt Daten von außerhalb benötigt. Zwar hat er genau das vor aber er erwähnt es nicht. Seine Intention ist nur, dass er zwei Zeilen Code weniger schreiben möchte. Dies ist einfach unbrauchbar und sorgt auch nicht für ein besseres Verständnis, sondern für mehr Verwirrung. Je mehr ich mir die Unterlagen anschaue, desto mehr wird mir auch die Probleme von @Tician klar. Der Lehrer versucht zwar die Basics einer imperativen Programmiersprache zu zeigen, versucht aber gleichzeitig prozedural in einer reinen objektorientierten Sprache zu entwickeln. Das kann einfach nicht klappen, ohne dass es verwirrend wird. Da kommen wir wieder zu dem Problem, was ich oben erwähnte. Wenn man einfach nicht die Zeit hat, die Objektorientierung zu erklären, dann sollte man auch nicht mit einer objektorientierten Sprache anfangen, sondern mit einer rein prozeduralen Sprache. Auch das wichtigste Werkzeug eines Entwicklers, wird nicht mal besprochen: Der Debugger. Ohne den Debugger könnte kein Entwickler überleben aber nirgends wird mal der Debugger erwähnt und das Problem sieht man hier doch auch: Der TE ist nicht in der Lage, seinen eigenen Code zu debuggen. Taucht ein Fehler auf, ist der TE sofort aufgeschmissen. Mag sein, aber das Problem sieht man doch hier überdeutlich: Der TE hat zwar Interesse nach mehr und möchte in der Firma ein eigenes Programm schreiben aber eckt überall an, weil er/sie überhaupt kein Verständnis für die Objektorientierung oder für C# besitzt. Man kann nicht einfach eine rein objektorientierte Sprache nehmen und die Objektorientierung weglassen.
-
Die Folien sind aus meiner Sicht totale Grütze ... Die kann man vielleicht in der 7. Klasse verwenden, damit die Schüler ein bisschen Spaß haben können aber für Azubis sollte da schon mehr Niveau sein. Wo ist Vererbung? Polymorphie? Generics? Sorry, aber ihr lernt nicht mal Ansatzweise Objektorientierung. Geschweige denn richtig mit C# umzugehen. Auch wenn er aus der Java-Welt kommen sollte, hat er dennoch nicht das Zeug dazu, echt das richtig beizubringen. Java unterscheidet sich von C# nicht so sonderlich viel. Meiner Meinung nach ist das Bullshit. Wenn man die Syntax richtig erklären würde, dann würde man auch das Konzept hinter der Syntax verstehen und dann lösen sich Syntax-Fehler von alleine. Man braucht da nicht irgendwelche Regeln auswendig lernen. Die kommen von alleine, wenn man einmal die Syntax verstanden hat... Aber Gut zum Thema: Ja, das ist richtig. C# verfolgt aber das Ziel Daten grundsätzlich mit einem Zuweisungsoperator zu manipulieren, während Methoden eine Aufgabe darstellt, die mit den Daten arbeitet. Wenn man, wie in der Java-Welt, Getter- und Setter-Methoden schreiben würde, würde man die Manipulation von Daten und Methoden vermischen und somit hätte man kein gleichmäßiges Bild mehr. Darum abstrahiert C# die Getter- und Setter-Methoden.
-
Das explizite Schreiben von Getter- und Setter-Methoden ist in C# unüblich. Das macht man in der Java-Welt. Im Allgemeinen finde ich dieses pdf-Dokument sehr schlecht. Ein Variablenname sollte nicht den Datentypen beinhalten. Das schränkt zu sehr ein. Angenommen, du musst aufgrund von Änderungen den Datentypen ändern. Dann musst du auch über den Variablennamen ändern. Den Datentyp im Variablennamen stammt noch aus der Zeit, als es noch keine gescheiten IDEs gab und der Entwickler Hilfskonstrukte benötigte. Außerdem geht man gar nicht darauf ein, wieso die Semikolons falsch sind. Es ist zwar nur eine Wiederholung aber wenn man die Schüler erklären würde, dass ein Semikolon das Ende einer Anweisung darstellt, dann sollte sich das von selbst erübrigen.
-
Genau. Der Entwickler benutzt es wie Members. Der Kompiler macht daraus später Methodenaufrufe. WriteLine besitzt weitere Signaturen. Darunter auch eine Signatur, die der String.Format()-Methode entspricht. Die {0} ist ein Platzhalter und wird gegen den ersten parameter - also value - ausgetauscht. Strings zu konkatenieren (mit dem +-Operator zusammenfügen) sollte man vermeiden, Das liegt an der Eigenheit der Strings. Strings sind immutable. D.h. unveränderbar. Der +-Operator nimmt die Werte und baut daraus einen neuen String. In diesem Fall macht es wenig Probleme aber stelle dir mal vor, du führst dies mehrere Tausend mal hintereinander aus. Dann wird das irgendwann sehr langsam, weil jedes Mal ein neuer String gebaut wird. Darum gibt es z.B. die String.Format()-Methode und die StringBuilder-Klasse, um Strings zu generieren, ohne dass jedes Mal zwischendurch ein neuer String gebaut werden muss. Mit dem neuen C# 6.0 gibt es inzwischen auch eine weitere lesbarere Variante: Console.WriteLine($"Nummer gesetzt auf {value}"); Diese Variante nennt sich String Interpolation. Die String Interpolation beginnt mit einem $-Zeichen. Danach werden die Variablen, die ausgewiesen werden sollen, in geschweifte Klammern gesetzt.
-
Mag sein, dass die Prüfer da nicht ganz so streng draufschauen, aber ich finde den Antrag sehr fragwürdig. Auf der einen Seite wird die Software als riesiges, komplexes Konstrukt dargestellt aber auf der anderen Seite wird gar nicht auf die komplexität eingegangen. Als erstes die Projektbeschreibung: Sie wird dargestellt als würde die Software komplexe Strukturen der Projekt-Phasen in unterschiedlichen Firmen abbilden, kontrollieren und steuern können. Die Aufgabe des Azubis ist die Implementierung der Basisfunktionalität. Gut, lassen wir es einmal so wirken. Bis jetzt liest sich wie ein PR-Text eines Vertrieblers, der den Wunschzustand erwähnt aber wünschen kann man sich ja vieles. Zur Nutzen/Kostenberechnung sage ich mal nichts. Das würde jetzt den Rahmen sprengen. Punkt 2: Hier wird es mal etwas konkreter, was die Software können soll: Projekte anlegen Projekte verwalten (auf welche Weise auch immer?) Projekte tabellarisch oder als Ganttdiagramm darstellen Das wars? Wo ist die erwähnte Steuerung und Kontrollierung der Projekte? Und das soll dann verkauft werden? Okay, vielleicht ist das auch nur die Basisfunktionalität. Wer weiß? Punkt 3.1: Du erwähnst, dass das Projekt mittels dem Entwicklungsmodel des Wasserfallmodell und der agilen Entwicklung entwickelt werden soll. Beides schließt sich aber gegenseitig aus. Das Wasserfallmodel beruht auf sehr starren Phasen, während die agile Entwicklung bestmöglich gar nicht aus Phasen besteht. Agile Entwicklung beruht auf vier Grundsätze: Menschen und Interaktionen stehen über Prozessen und Werkzeugen Funktionierende Software steht über einer umfassenden Dokumentation Zusammenarbeit mit dem Kunden steht über der Vertragsverhandlung Reagieren auf Veränderung steht über dem Befolgen eines Plans Das Wasserfallmodell verstößt schon gegen drei der vier Grundsätze. Ich nehme mal an, du meinst eher das V-Modell. Punkt 3.2: Wieso wird so oft MySQL erwähnt? Mag ja sein, dass ihr MySQL verwendet aber ihr wollt die Software verkaufen, also muss sie auch mit anderen Datenbanken zurecht kommen. Angenommen, ein Kunde hat MSSQL oder OracleDB im Einsatz. Was dann? Punkt 3.3: In der Implementierungsphase wird mit vier Sätzen ein generisches Login-System beschrieben. Das Gantt-Diagramm muss mit einem Satz auskommen. Wie wird das Diagramm überhaupt generiert? Ist das eine HTML-Tabelle? Eine Grafik? Schreibst du die Bibliothek dafür selber? Wird da was fertiges verwendet? Die eigentliche Aufgabe der Software wird hier gar nicht beschrieben. Ist das generieren des Gantt-Diagramms überhaupt deine Aufgabe oder implementierst du nur das Login-System? Punkt 4: In der "Entwurf"-Phase designst du 9 Stunden lang Datenbank-Tabellen. Wozu? In der Phase "Implementierung" lässt du diese Tabellen mit dem Entity Framework generieren. Auch designst du in der "Entwurf"-Phase noch Views. Wozu? Weshalb? Welchen Grund haben die Views? Willst du die komplette Business-Logik als Views abbilden? Das halte ich für fatal. Ihr habt doch das mächtige Entity Framework und bitte sag mir jetzt nicht, dass ihr das Framework nicht richtig einsetzt und nur stumpf SQL-Queries mit der ExecuteQuery()-Methode ausführt. Fazit: In der gesamten Projektbeschreibung wird aus meiner Sicht überhaupt nicht klar, was du machen möchtest. Es wird eine angeblich riesige Software vorgestellt, die aber in Wirklichkeit nur sehr klein ist und auf deine Aufgabe gehst du nicht mal ein. Der Hauptaugenmerk liegt irgendwie beim Login-System aber das kann doch nicht deine einzige Aufgabe sein. Ansonsten das noch, was @stefan.macke schrieb.
-
Und wer bezahlt die Wohnung? Mit Sicherheit nicht der Azubi selbst, wenn man bedenkt, dass ein Azubi oft nicht mal volljährig ist, wenn er die Ausbildung anfängt ... Ich nehme nur mal Raum Hamburg, wo die Kalt-Miete einer Ein-Zimmer-Wohnung schon das durchschnittliche Einkommens eines Azubis übersteigen kann. Von der Kaution will ich gar nicht sprechen. Da bleibt nichts anderes übrig, als in Hotel Mama weiterzuwohnen oder die Eltern bezahlen die Wohnung. Mag sein, dass es Gegenden gibt, wo sich Azubis eine Wohnung leisten können, aber dies ist bei weitem nicht überall so. Selbst Studium ist nicht gleich Studium. Ich kenne inzwischen einige Bachelor-Absolventen. Sowohl von Fachhochschulen als auch von Universitäten und irgendwie ist jeder der Meinung, dass Fachhochschulen praxisorientierter aber stressiger sind, als Universitäten und das deckt sich auch mit meinen Erfahrungen, da ich in meiner Assistenten-Ausbildung die meist die Kurse und Vorlesung, wie auch die FH-Studenten, die im selben Hause studierten, besuchte und sehr häufig musste ich auch noch die Nacht durcharbeiten, weil am nächsten Morgen um 8 Uhr der Abgabetermin der Übungen war. Zu meiner Zeit als Azubi kam sowas nie vor.
-
Ich würde eigentlich sogar noch einen Schritt weitergehen: Weg von Powerpoint! Ich finde, es gibt nichts langweiligeres als Powerpoint-Präsentationen. Gerade ITler wollen nicht mit Zahlen und Fakten gelangweilt werden, sondern die wollen etwas sehen. Ich würde es langweilig finden, wenn jemand ein Vortrag über ein Stück Code hält und dabei nur ein Folien zeigt, anstatt die IDE, womit man den den Code direkt "anfassen" und ausprobieren kann. Außerdem bin ich der Meinung, dass Powerpoint nur etwas für Leute ist, die technisch keine Ahnung haben. Ich bin ein Freund von HTML-Präsentationen. Das läuft in jedem Browser und man braucht keinen unsinnigen Powerpoint-Viewer. Die Zuschauer brauchen auch nur den Link und können sich noch mal die Präsentation anschauen. Da schmeiße ich mal reveal.js in den Raum. Das ist ein Framework für schicke HTML-Präsentationen. Der Vorteil ist auch, dass man hier nur mit reinen Text arbeitet und mit Hilfe einer Quellcodeverwaltung Änderungen an der Präsentation leicht nachvollziehen lassen können. So habe ich schon einige Vorträge auf Konferenzen gesehen, die gleich auf der Bühne korrigiert und online gestellt worden sind. Für dieses Framework gibt es auch einen visuellen Editor. Wenn man also gerade in der Abschlusspräsentation beweisen möchte, dass man was drauf hat, würde ich von Powerpoint Abstand halten und schauen, ob es da nicht bessere Alternativen gibt und auch wenn man sich gegen Powerpoint entscheiden sollte, sollte man gerade bei Präsentationen, die hauptsächlich ITlern ansprechen sollte, mit Folien sparsam sein. Ob man jetzt Witze einbaut, sollte jeder für sich selbst entscheiden. Es gibt Leute, die bringen Witze sehr gut rüber und können die Präsentation ein wenig auflockern. So gibt es bei mir in der Firma jemanden, der selbst langweilige und trockene Präsentationen zu Themen, wie z.B. Marktanalysen, sehr unterhaltsam präsentieren kann. Andere können es wiederum nicht und bei solchen Leuten wirken Witze wie erzwungen.
-
Die Frage ist, wie sollen wir dir nun helfen? Ich kann dir die erste Frage in deinem ersten Post beantworten. Die Frage ist dann aber, ob du das überhaupt verstehst. Und das führt mich zu folgendes: Ich behaupte mal frech: Nein, du kannst es nicht. Zumindest noch nicht. Programmieren ist mehr, als nur ein paar Zeilen Code zu schreiben, die man nicht versteht. Das du den Code selber nicht verstehst, sieht man daran, dass du Kommentare brauchst, um den Code zu erklären, damit du noch am nächsten Tag weißt, was der überhaupt macht. Ich sehe hier zwei große Probleme, die du erstmal in den Griff bekommen müsstest, um weiterkommen zu können: Du musst die Objektorientierung verstehen Du musst das Konzept bzw. die Syntax von C# verstehen Dir ist offenbar nicht klar, dass Klassen aus Methoden und Eigenschaften bestehen. Zugriffsmodifizierer In C# kann man mit Hilfe der Zugriffsmodifizierer die Sichtbarkeit der Methoden und Eigenschaften bestimmen: public: Die Methode/Eigenschaft ist von außen sichtbar private: Die Methode/Eigenschaft steht nur der direkten Klasse zur Verfügung; sie ist von außen nicht sichtbar protected: Die Methode/Eigeschaft steht der direkten und vererbten Klasse zur Verfügung; sie ist von außen nicht sichtbar internal: Die Methode/Eigenschaft steht nur im eigenen Projekt zur Verfügung. internal ist mehr ein Sonderling und kommt in der Praxis relativ selten vor. Es wird oft verwendet, wenn man private Klassen in einem Unittest testen möchte, da man die Möglichkeit besitzt, den Zugriff auf solche Klassen dennoch in anderen Projekten zu erlauben. Dies muss man aber explizit in der Projekt-Datei angeben. Eigenschaften Eigenschaften lassen sich über get abrufen und über set setzen. Eigenschaften definiert man wie folgt: class A { public int Nummer { get; set; } } Bei dieser Art der Implementierung einer Eigenschaft spricht man auch von einer "automatisch implementierten Eigenschaft", da der C#-Kompiler dahergeht und Standard-Getter- und Setter-Methoden generiert, da der getter- und setter nicht ausprogrammiert worden sind. Der Kompiler generiert daraus folgenden Code: class A { private int nummer; public int get_Nummer() { return this.nummer; } public void set_Nummer(int value) { this.nummer = value; } } Wie man sehen kann, wird dann ein privates Feld und eine öffentliche get- und set-Methode generiert, mit denen man das Feld von außen steuern kann. Natürlich kann man auch hier die Sichtbarkeit einschränken. Beispiel: class A { public int Nummer { get; private set; } } Der Getter ist dann öffentlich (public) und der Setter ist nicht öffentlich (private). Natürlich kann man auch das public gegen einen anderen Modifizierer ersetzen: class A { protected int Nummer { get; set; } } In diesem Beispiel ist der Getter- und Setter protected. Also nur in der direkten und vererbten Klasse sichtbar und von außen nicht. Man kann auch selbst den Getter- und Setter implementieren, wenn man möchte, dass noch zusätzlich was passiert. Häufig ist dies der Fall, wenn man ein Event auslösen möchte, wenn eine Eigenschaft sich ändert. Dann muss man auf die automatische Implementierung der Standard Getter- und Setter-Methoden verzichten und es selbst schreiben: Beispiel: public class A { private int nummer; public int Nummer { get { return this.nummer; } set { Console.WriteLine("Nummer gesetzt auf {0}", value) this.nummer = value; } } } In diesem Beispiel wird auf der Konsole der neue Wert für Nummer ausgegeben. In der Set-Methode steht die Variable value zur Verfügung, die den neuen Wert besitzt. Der Kompiler würde daraus folgenden Code erzeugen: class A { private int nummer; public int get_Nummer() { return this.nummer; } public void set_Nummer(int value) { Console.WriteLine("Nummer gesetzt auf {0}", value) this.nummer = value; } } Die Schreibweise mit get {...} und set {...} ist also nichts weiter als syntaktischer Zucker, um den Code kompakter zu machen. Daraus werden dann auch nur Methoden generiert. Methoden Methoden können einen Rückgabewert besitzen oder nicht. Wie man schon beim generierten Getter- und Setter-Methoden der Eigenschaften sehen kann, gibt ein void an, dass die Methode kein Rückgabewert besitzt. Ersetzt man void hingegen gegen einen Datentyp, so gibt die Methode einen Wert vom genannten Datentyp zurück. Beispiel: public string GetHallo() { return "Hallo"; } Die Methode GetHallo() gibt den String "Hallo" zurück. Zu deiner ursprünglichen zweiten Frage: Ich habe mir mal den Code vom StreamReader angeschaut. Die Dispose()-Methode ruft Close() auf. Sprich, wenn du um den StreamReader ein using machst, wird automatisch Close() aufgerufen, wenn Dispose() aufgerufen wird. Hier mache ich aber auch erst mal schluss, da ich nicht weiß, ob du überhaupt verstehst, was ich hier geschrieben habe. Wenn du es verstanden haben solltest, kann ich noch was zu Klassen und Generics schreiben.
-
Sorry, aber ich kann nichts dafür, wenn du mit dem großen 1x1 anfangen willst, auch wenn du das kleine nicht kannst. Dann muss ich sagen, dann ist das Projekt noch zu groß für dich. Dann fange mit kleineren Dingen an. Bei deinem Projekt brauchst du schon etwas mehr Übung und Erfahrung, um es wirklich auf die Beine stemmen zu können. Du hast vor, mehrere komplexe Themen zu bearbeiten und du verstehst nicht mal, wie man das erste Thema löst. Dann kaufe ein Buch für Anfänger und arbeite es durch. So wird das einfach nichts.
-
Ich verstehe deine Nummerierung nicht. Zuerst gibst du an, dass die CSV-Datei so aufgebaut ist: Datum, Packstück-Nummer, Auftrags-Nummer, Paketnummer, Bezeichnung, Menge, Lagerplatz Dann sagst du, dass du die siebte Nummer braucht und das wäre nach meiner Zählung "Lagerplatz". Wo kommt denn deine "7. Nummer her"? Von was?
-
Das virtual könnte man auch weglassen. Ich schreibe es nur aus Gewohnheit hin, weil das NHibernate-Framework dies so möchte. Außerdem bietet es mir beim Testen gewisse Vorteile. virtual bedeutet, dass diese Eigenschaft mittels Vererbung überschreibbar ist. Für gewöhnlich sind Eigenschaften und Methoden in C# nicht überschreibbar. Wenn man in einer vererbten Klasse eine Eigenschaft oder Methode aber überschreiben möchte, so muss sie in der Basis-Klasse als virtual definiert werden. Beispiel: public class A { public virtual string Hallo { get { return "Hallo"; } } } public class B : A { public override string Hallo { get { return base.Hallo + " Welt"; } } } Die Eigenschaft Hallo in Klasse A liefert "Hallo" zurück, während die Klasse B "Hallo Welt" zurückliefert. Die Klasse B überschreibt die Eigenschaft von Klasse A und ruft mit base.Hallo erst mal die Eigenschaft in Klasse A auf und modifiziert diesen Wert. Was ist denn die "5. Nummer jeder Zeile"? Welche Spaltenüberschrift besitzt dann diese Zeile?
-
Ich nehme mal an, dass das aus der Logistik kommt. Ich kenne mich da mit den Begrifflichkeiten nicht aus. Ich nehme aber mal an, dass Daten aus deiner Firma sind. Die Daten stammen ja mit Sicherheit auch aus einer Datenbank, also muss das Kind bei euch ja einen Namen haben. Frage doch deinen Ausbilder. Spontan und ohne den Kontext zu kennen, würde ich aber behaupten, dass es sich hierbei um eine Kanban-Karte für einen Logistiker handelt, der mit diesen Informationen die Pakete packt. Unabhängig von dem Klassennamen kannst du aber dennoch schon den Inhalt der Klasse füllen: public class Xyz { public virtual DateTime Datum { get; set; } public virtual int PackstueckNummer { get; set; } public virtual int Auftragsnummer { get; set; } public virtual int Paketnummer { get; set; } public virtual string Bezeichnung { get; set; } public virtual int Menge { get; set; } public virtual string Lagerplatz { get; set; } } Für Xyz muss dann noch ein passender Name gefunden werden. Bei PackstueckNummer, Auftragsnummer, Paketnummer und Lagerplatz musst du dann mal schauen, ob die Datentypen richtig sind. Ich kenne die Daten nicht. Kann auch sein, dass Buchstaben erlaubt sind, dann müssen es Strings sein.
-
Wie lernt man effektiv eine Programmier-Sprache?
Whiz-zarD antwortete auf KampfKatze's Thema in IT-Weiterbildung
Einfacher geht es kaum noch. Ich versuche es aber mal. Du hast eine For-Schleife. Im Kopf stehen folgende Informationen: Die Zählervariable heißt i => int i = 0 i wird mit 0 initialisiert => int i = 0 Die Schleife läuft so lange, wie i kleiner 5 ist => i < 5 Pro Schleifendurchlauf wird i um 1 erhöht => i++ Das bedeutet, du hast 5 Schleifendurchläufe bei jedem Schleifendurchgang wird folgende Logik angewendet: if (i == 3) { result += 10; } else { result += i; } D.h. wenn i gleich 3 ist, dann wird auf result 10 addiert. Ansonaten i. Jetzt gehen wir die Durchläufe Schritt-für-Schritt durch: Durchlauf: i = 0, result = 0 i ist nicht 3, also wird auf result 0 addiert. result ist 0; also: result = result + i = 0 + 0 = 0 Durchlauf: i = 1, result = 0 i ist nicht 3, also wird auf result 1 addiert. result ist 0; also: result = result + i = 0 + 1 = 1 Durchlauf: i = 2, result = 1 i ist nicht 3, also wird auf result 2 addiert. result ist 1; also: result = result + i = 1 + 2 = 3 Durchlauf: i = 3, result = 3 i ist 3, also wird auf result 10 addiert. result ist 3; also: result = result + 10 = 3 + 10 = 13 Durchlauf: i = 4, result = 13 i ist nicht 3, also wird auf result 4 addiert. result ist 13; also: result = result + i = 13 +4 = 17 Beim 6. Durchlauf hätte i den Wert 5 und somit entspricht i nicht mehr der Bedingung, dass es kleiner als 5 ist und bricht die Schleife ab. result ist dann 17 und wird in der Konsole ausgegeben. -
Wie lernt man effektiv eine Programmier-Sprache?
Whiz-zarD antwortete auf KampfKatze's Thema in IT-Weiterbildung
Und wo genau liegt das Problem? Gehen wir mal die Schleife durch: i result ------------------------------------ 0 result += 0 => result = result + 0 => result = 0 + 0 = 0 1 result += 1 => result = result + 1 => result = 0 + 1 = 1 2 result += 2 => result = result + 2 => result = 1 + 2 = 3 3 result += 10 => result = result + 10 => result = 3 + 10 = 13 4 result += 4 => result = result + 4 => result = 13 + 4 = 17 Auf result wird pro Schleifendurchlauf immer i dazu addiert. Die Ausnahme ist, wenn der Zähler i bei 3 ist. Dann wird 10 draufaddiert. Der += operator ist nur eine Abkürzung result += i ist das selbe wie result = result + i -
Wie lernt man effektiv eine Programmier-Sprache?
Whiz-zarD antwortete auf KampfKatze's Thema in IT-Weiterbildung
Der Code ist nicht vollständig. Der Kopf der For-Schleife ist nicht vollständig. Und was machst du gerade? Bis jetzt sehe ich nur, dass wenn der Zähler i gleich 3 ist, auf das Ergebnis 10 addiert wird, ansonsten 1. -
C# selbstständig lernen - Projektideen, wichtige Themen
Whiz-zarD antwortete auf Unstoppable's Thema in IT-Weiterbildung
Web-Technologie und C# schließen sich nicht aus. Eine moderne Web-Applikation besteht aus Microservices und wie die Microservices entwickelt wurden, ist dem Browser schnuppe. Das kann jetzt C#, F#, Java, Python, C, C++, Go, Fortran, R oder was auch immer sein. Die Web-Applikation kommuniziert mit dem Server über eine Web-API und holt sich dort die Daten ab. Das HTML-Gerüst wird dann im Browser mittels JavaScript-Frameworks wie z.B. AngularJS oder React clientseitig gerendert. Daher trennt man zwischen Frontend- und Backend-Entwickler. Frontend-Entwickler machen den clientseitigen JavaScript-Kram, während der Backend-Entwickler sich auf dem Server austobt. AngularJS benutzt als Sprache auch TypeScript, was Ähnlichkeiten mit C# aufweist und auch von Microsoft ist. Gerade Microservices bieten die Möglichkeit, sehr flexibel mit der Programmiersprache zu sein. Ist es besser, eine Aufgabe mit F# zu entwickeln, dann nimmt man halt F#. Für eine andere Aufgabe ist C# vielleicht besser. Man legt sich hier also nicht auf eine Sprache fest, sondern man wählt die geeignete Sprache. Das selbe gilt auch für die Datenhaltung. Bei sog. Monolithen ist es oft der Fall, dass man sich für eine relationale Datenbank entscheidet aber vielleicht ist so eine Datenbank für bestimmte Aufgaben nicht flexibel genug. Für bestimmte Microservices nimmt man dann vielleicht eine NoSQL-Datenbank oder vielleicht sogar einen ganzen Hadoop-Cluster, während andere wiederum weiterhin mit einer relationalen Datenbank arbeiten. Was Mobile angeht, sollte man sich nicht fragen, wo dort C# steht, denn C# hat seinen Platz eher im Backend, sondern die Frage, ob es noch Sinn macht, native Apps zu entwickeln? Bei Spielen macht es vielleicht noch Sinn aber bei Apps, die auch als Web-Applikation laufen können? Inzwischen können auch Browser auf die Sensoren zugreifen und auswerten. Der Bedarf an nativen Apps sinkt also meiner Meinung nach. Abgesehen davon gibt es auch noch im Frontend-Bereich Xamarin, womit man Android-, und iOS-Apps nativ mit C# entwickeln kann. Für die iOS-Kompilierung ist aber ein Mac von nöten. -
Eine CSV-Datei ist ja auch nichts weiteres, als eine Tabelle. Was für Daten stecken denn in der Datei? Ob die Daten doppelt und dreifach sind, ist ja auch erstmal egal. Ein Problem nach dem anderen.
-
Wie lernt man effektiv eine Programmier-Sprache?
Whiz-zarD antwortete auf KampfKatze's Thema in IT-Weiterbildung
Suche unter Google nach "coding katas" und versuche sie zu bearbeiten. Eine Liste findest du z.B. hier -
Mein Beispiel ist bei weitem nicht perfekt. Ich wollte dich auch nicht entmutigen, sondern einfach zeigen, dass auch erfahrene Entwickler erstmal anfangen und dann den Code stückweise verbessern. Niemand schreibt auf Anhieb guten Code. Man muss aber Erfahrungen sammeln, um ein Gefühl für die Sprache zu bekommen. Mit Erfahrungen merkt man auch, wenn etwas vielleicht nicht ganz so elegant ist und man vielleicht noch mal drüber nachdenken sollte. Ich wollte nur aufzeigen, wie ich an solche Dinge rangehe. Du solltest einfach Mut besitzen, mal etwas auszuprobieren. Kaputtmachen kannst du ja nichts. Wenn du sogar eine quellcodeverwaltung, wie z.B. Git, nutzt, dann kannst du sogar ganze Änderungen wieder rückgängig machen. Du kannst auch Fragen stellen und mit anderen Leuten über dein Code reden. Ich denke, niemand reißt dir deswegen den Kopf ab. Das einzige, was ich erwarte, ist, dass man auch die Ratschläge von anderen annimmt und sie mal ausprobiert.
-
C# selbstständig lernen - Projektideen, wichtige Themen
Whiz-zarD antwortete auf Unstoppable's Thema in IT-Weiterbildung
Um Dinge zu lernen, geht es viel weniger um tolle Projekte, sondern um Techniken zu lernen: O/R-Mapper (Entity Framework, NHibernate) IoC/DI container (z.B. StructureMap, AutoFac) Logging (z.B. SeriLog, NLog) Message Queues (z.B. RabbitMQ) Unittests Microservices Web-APIs OData Linq Oder du optimierst dein Programmierstil. Lerne Clean Code und TDD (Test-driven Development) und verinnerliche die SOLID-Prinzipien. Selbst wenn du eine WinForms-Anwendung gebaut hast, könntest du mit Sicherheit diese noch weiter optimieren. z.B. kannst du versuchen, diese mit dem MVP-Pattern (Model-View-Presenter) umzubauen oder du verwendest das Event-Aggregator-Pattern um die Kommunikation zwischen den einzelnen Forms zu realisieren. Eigentlich gibt es immer was zu optimieren und kann dabei neue und nützliche Dinge lernen. Ich finde, man muss diese Techniken nicht alle bis zur Perfektion verinnerlicht haben. Ich finde, man sollte aber mal davon gehört und ggf. auch ein mal ausprobiert haben. Die Vertiefung einzelner Techniken kommt hinterher, wenn man ein Projekt gefunden hat, was man umsetzen möchte. -
Fachinformatiker = Informatiker 2. Klasse?
Whiz-zarD antwortete auf wisdomsoz's Thema in IT-Weiterbildung
Ich habe eine Assistenten-Ausbildung gemacht aber auf einer Schule die, zumindest in Raum Hamburg und Schleswig-Holstein, einen sehr guten Ruf genießt und ich denke auch, dass die Fachinformatiker-Ausbildung noch sehr viel Verbesserungspotenzial besitzt aber es kommt immer darauf an, was man später daraus macht. Ein Studium macht dich auch nicht zu einem Super-ITler, der ein Allround-Genie ist. Zuerst solltest du dir mal überlegen, was du eigentlich möchtest? Möchtest du eher Software entwickeln oder lieber die IT-Infrastruktur am Leben erhalten (ich nenne es einfach mal so)? Beides sind doch sehr unterschiedliche Berufsfelder, auch wenn sie einen gewissen Schnittpunkt haben. Ein FISI wird z.B. wenig mit Java arbeiten und ein FIAE wenig Netzwerke- und Server administrieren. Dann kommt es darauf an, was du aus einem Abschluss machst. Selbst mit einem Studium-Abschluss kannst zu einem Entwickler versauern, der nach kurzer Zeit zu nichts zu gebrauchen ist, wenn man nicht bereit ist, sich weiterzuentwickeln. Falls du dich mehr für Softwareentwicklung begeisterst, brauchst du eigentlich auch weniger Zertifikate. Bei einem Entwickler kommt es eigentlich mehr auf die Projekte an, an denen er mitgewirkt hat und ehrlich gesagt, wüsste ich auch nicht, welche Zertifikate man da überhaupt machen könnte. Ob man die 2.000 € Netto erreicht, hängt auch von der Branche ab, wo man arbeiten möchte. Aus Erfahrung weiß ich, dass man in der Spielebranche kaum die 2.000 € erreichen wird. Dort ist die Bezahlung eher mies. In der Finanz- oder Versicherungsbranche sieht die Welt auch schon wieder ganz anders aus. Die Qualifikation ist also nicht immer entscheidend. Ich arbeite in der Finanzbranche und ich habe dein Wunschgehalt schon in wenigen Jahren erreicht. Auch ohne Zertifikate oder Studium. -
Wieso sollte man dich töten wollen? Softwareentwicklung ist nun mal ein Reifeprozess. Niemand liest nur ein Buch und kann gleich wunderbar sauberen Code schreiben. Mein Code sah zum Anfang auch mies aus und selbst Robert C. Martin, der das Buch "Clean Code" geschrieben hat, sagt von sich aus, dass er nicht die Weisheit mit Löffeln gefressen hat und es auch bei seinen Code-Beispielen sicherlich noch Verbesserungspotenzial gibt aber nur durch Ausprobieren lernt man. Du hast schon richtig erkannt, dass man fürs Einlesen der Datei eine eigene Klasse benötigt. Allerdings gehört die Logik nicht in den Konstruktor. Der Konstruktor dient zur Initialisierung der Klasse. Der Name der Klasse sollte auch die Aufgabe widerspiegeln, was die Klasse tut. "DateiEinlesen" ist vielleicht gut, aber geht es vielleicht noch konkreter? Ich weiß, dass es eine CSV-Datei ist. Vielleicht eher CsvReader? Wobei dieser Name auch wieder sehr allgemein ist. In der CSV-Datei steckt ja eine Tabelle. Welche Daten besitzt die Tabelle? Vielleicht kann man der Tabelle einen Namen geben. Eine CSV-Datei ist ja eine Art der Serialisierung. Das Verfahrung um so eine Tabelle in ein Objekt zu überführen, nennt man auch Deserialiserung. Das kann man ja erst mal im Hinterkopf behalten. Zuerst würde ich mir aber erst mal eine geeignete Datenstruktur überlegen. In der CSV-Datei stecken ja Daten. Ich nehme jetzt mal als Beispiel, dass die CSV-Datei Daten zu Personen beinhaltet: Name;Vorname;Geschlecht;Alter Doe;John;Maennlich;38 Also würde ich erst mal eine Klasse für diese Daten erstellen: public class Person { public string Name { get; set; } public string Vorname { get; set; } public Geschlecht Geschlecht { get; set; } public int Alter { get; set; } } public enum Geschlecht { Maennlich , Weiblich } Nun könnte ich mich darum kümmern, eine(!) Datei einzulesen. Ich habe eine Datenstruktur und ich weiß, dass ich eine CSV-Datei deserialisieren muss. Also könnte man die Klasse z.B. PersonCsvDeserializer nennen. In dieser Klasse soll es eine Methode geben, die Deserialize() heißt. Ich verzichte hier jetzt erst mal bewusst auf ein Interface, weil ich denke, dass es für dich bis hier hin schon kompliziert genug ist. Das Interface werde ich später noch mal erklären. Erst mal kümmern wir uns darum, was wir alles brauchen, um eine Datei zu deserialisieren. Was muss die Klasse PersonCsvDeserializer alles wissen, um eine CSV-Datei deserialisieren zu können? Man könnte vielleicht im ersten Schritt auf die Idee kommen, dass die Klasse den Pfad und Dateinamen benötigt. Mit den Informationen aus dem letzten Absatz könnte ein erster Entwurf so aussehen: public class PersonCsvDeserializer { public IEnumerable<Person> Deserialize(string fileName) { // ... } } Als Rückgabewert habe ich IEnumerable<Person> gewählt, weil IEnumerable<T> ein sehr allgemeines Interface ist und einen Enumerator (auf deutsch: Aufzählung; in anderen Sprachen auch Iterator genannt) zur Verfügung stellt, mit dem wir über die Daten iterieren können (mit der foreach-Schleife). Sowohl IList<T>, ICollection<T>, IDictionary<T>, Array und weitere Klassen implementieren dieses Interface und mehr als über die Daten iterieren wollen wir nicht. Wenn wir später damit mehr machen wollen, können wir es leicht mit Linq in eine Collection, List, Array oder auch in ein Dictionary umwandeln. Die Deserialize()-Methode soll also eine Aufzählung von Personen zurückliefern. Normalerweise macht man es anders, aber aus einfachheit behaupte ich mal frech, dass die erste Zeile in der CSV-Datei immer ein Header besitzt. In der Implementierung überspringe ich den Header per Linq mit der Skip()-Methode. Die Deserialize()-Methode soll also folgendes machen: Die Datei lesen Durch die Datenzeilen iterieren Pro Datenzeile ein Person-Objekt erstellen Die Person-Objekte als Aufzählung zurückliefern Der erste Entwurf könnte daher folgendermaßen aussehen: public class PersonCsvDeserializer { public IEnumerable<Person> Deserialize(string fileName) { IList<Person> result = new List<Person>(); foreach (string line in File.ReadAllLines(fileName).Skip(1)) { string[] elements = line.Split(';'); result.Add(new Person { Name = elements[0], Vorname = elements[1], Geschlecht = (Geschlecht)Enum.Parse(typeof(Geschlecht), elements[2]), Alter = Convert.ToInt32(elements[3]) }); } return result; } } Die Methode macht zwar was sie soll, aber ist sie wirklich übersichtlich? Nicht wirklich. Wir haben hier mehrere Ebenen miteinander vermischt. Wir können also mit dem Refactoring anfangen. z.B. das File.ReadAllLines(fileName).Skip(1) Wofür ist das genau gut? Wenn man den gesamten Kontext kennt, weiß man es zwar aber eigentlich liegt der Code-Abschnitt eine Ebene Tiefer. Es hantiert mit Dateien und hat mit der eigentlichen Aufgabe der Deserialiserung wenig zu tun. Also sollte man diesen Teil in eine separate Methode packen: private IEnumerable<string> ReadDataFromFile(string fileName) { return File.ReadAllLines(fileName).Skip(1); } Somit wandert das Skip(1) in eine tiefere Ebene und interessiert uns in der Deserialize()-Methode nicht mehr. Als nächstes fällt aber auf, dass wir ein String mit Split() in ein Array teilen und aus diesem Array dann die einzelnen Personendaten herausfischen. Diesen Vorgang nennt man auch Parsing. Also könnten wir diesen Teil auch in eine Methode auslagern: private Person Parse(string serializedData) { string[] elements = serializedData.Split(';'); return new Person { Name = elements[0], Vorname = elements[1], Geschlecht = (Geschlecht)Enum.Parse(typeof(Geschlecht), elements[2]), Alter = Convert.ToInt32(elements[3]) }; } Unsere Klasse sieht dann bis jetzt folgendermaßen aus: public class PersonCsvDeserializer { public IEnumerable<Person> Deserialize(string fileName) { IList<Person> result = new List<Person>(); foreach (string serializedData in ReadDataFromFile(fileName)) { Person person = this.Parse(serializedData); result.Add(person); } return result; } private IEnumerable<string> ReadDataFromFile(string fileName) { return File.ReadAllLines(fileName).Skip(1); } private Person Parse(string serializedData) { string[] elements = serializedData.Split(';'); return new Person { Name = elements[0], Vorname = elements[1], Geschlecht = (Geschlecht)Enum.Parse(typeof(Geschlecht), elements[2]), Alter = Convert.ToInt32(elements[3]) }; } } Nun ist Deserialize() doch recht gut lesbar. Wir lesen die Daten aus der Datei, parsen die Daten und erhalten ein Person-Objekt, welches wir dann in eine Liste packen und zum Schluss geben wir die Liste zurück. Es gäbe hier noch weiteres Verbesserungspotenzial aber ich belasse es erst mal hierbei. Ein paar Hinweise gebe ich aber noch: Fehler-Handling? Was passiert, wenn z.B. die Datei nicht existiert? Ist das erzeugte Objekt List<Person> wirklich eine gute Wahl? Angenommen, wir haben es mit einer riesigen CSV-Datei (mehrere Gigabytes) zu tun, die größer ist, als unser Arbeitsspeicher. Hier schmeiße ich mal das "yield return"-Schlüsselwort in den Raum. Auch ist das indexierte Zugreifen auf das Array in der Methode Parse() nicht wirklich glücklich gelöst. Was passiert nämlich, wenn mal eine Spalte in der Datei hinzukommt? Dann muss man ja auch den Code anpassen. Das will man aber eigentlich gar nicht. Zu diskutieren wäre auch, ob die Variable fileName nicht doch besser eine Instanzvariable sein sollte, die per Konstruktor reingereicht wird. Es fällt ja auf, dass die Methoden Deserialize() und ReadDataFromFile() den Dateinamen benötigen. Also stellt fileName ja eine gewisse Abhängigkeit dar, die die Klasse benötigt, um arbeiten zu können. Als Überlegung kannst du ja selber mal schauen, wie man mit solchen Situation umgehst. Um später im Hauptpgramm alle Personen zu iterieren könntest du nun folgendes schreiben: static void Main(string[] args) { string sourcePath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\blabla"; IEnumerable<string> fileNames = Directory.GetFiles(rootPath, "*.csv"); PersonCsvDeserializer deserializer = new PersonCsvDeserializer(); foreach(string fileName in fileNames) { IEnumerable<Person> persons = deserializer.Deserialize(fileName); foreach (Person person in persons) { // ... } } } Nach dem selben Prinzip, wie bei der PersonCsvDeserializer-Klasse kannst du ja mal überlegen, wie man nun diesen Code refactoren an. Ab hier wird es noch etwas technischer und tiefgreifender. Ich möchte dir noch zwei Techniken zeigen, die du aber erst mal nicht umsetzen brauchst. "Inversion of Control" und "Dependeny Injection" In der Klasse PersonCsvDeserializer fällt auf, dass die Klasse von einer Datei abhängig ist aber die Daten können vielleicht aus einer Datenbank kommen oder wir schreiben die CSV-Daten direkt in eine grafische Oberfläche. Möchte man jetzt für jeden Anwendungsfall eine eigene Klasse schreiben? Eigentlich nicht. Die Abhängigkeit zur Datei muss also aufgelöst werden. Das .Net-Framework bietet ja die abstrakte Klasse TextReader, die so ziemlich alles darstellen kann. Ein Reader, der eine Datei liest oder aus einem TCP-Stream oder aus einer Datenbank, etc. Anstatt also den Dateinamen reinzureichen, könnte man auch ein TextReader reinreichen. Hier mal ein Beispiel, wie so eine Klasse aussehen könnte: public class PersonCsvDeserializer { private TextReader reader; private bool isHeaderSkipped; public PersonCsvDeserializer(TextReader reader) { this.reader = reader; } public IEnumerable<Person> Deserialize() { string serializedData; while ((serializedData = this.ReadNextData()) != null) { Person person = this.Parse(serializedData); yield return person; } } private string ReadNextData() { string serializedData = this.reader.ReadLine(); if (!this.isHeaderSkipped) { this.isHeaderSkipped = true; return this.ReadNextData(); } return serializedData; } private Person Parse(string serializedData) { string[] elements = serializedData.Split(';'); return new Person { Name = elements[0], Vorname = elements[1], Geschlecht = (Geschlecht)Enum.Parse(typeof(Geschlecht), elements[2]), Alter = Convert.ToInt32(elements[3]) }; } } Die Main-Methode sieht dann so aus: static void Main(string[] args) { string sourcePath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\blabla"; IEnumerable<string> fileNames = Directory.GetFiles(rootPath, "*.csv"); foreach(string fileName in fileNames) { using (TextReader reader = File.OpenText(fileName)) { PersonCsvDeserializer deserializer = new PersonCsvDeserializer(reader); IEnumerable<Person> persons = deserializer.Deserialize(); foreach (Person person in persons) { // ... } } } } Zugegeben, in diesem Beispiel ist die Klasse PersonCsvDeserializer etwas komplizierter geworden aber es ist jetzt egal, woher die Daten stammen, solange wir ein TextReader in den Konstruktor schieben. Das reinrechen der Abhängigkeit in den Konstruktor nennt sich auch "Dependeny Injection". In diesem Beispiel habe ich auch das yield return verwendet. Da wir jetzt nur noch maximal den Speicher für ein Person-Objekt verbrauchen, könnte die Klasse eigentlich nun unendlich viele Daten deserialisieren. Ein Problem stellt aber immer noch die Indexierung des Arrays dar aber das überlasse ich jetzt dir. Das Interface Das letzte, was ich noch schreiben wollte, wäre ein geeignetes Interface für den Deserializer. Wollen wir jetzt mehrere Deserializer schreiben oder einen Deserializer als Abhängigkeit in eine Klasse reinreichen, ist ein Interface geeignet, damit es später egal ist, um welchen Deserializer es sich handelt. Man könnte sich ja auch vorstellen, dass die Daten nicht in einer CSV-Datei stecken, sondern in einer XML-Datei. Dafür wäre folgendes Interface recht nützlich public interface IDeserializer<T> { IEnumerable<T> Deserialize(); } Mit diesem Interface könnten wir sogar das hässliche using im Hauptprogramm wieder loswerden. Ich finde, das using stört im Lesefluss. Wir haben ja jetzt eine Klasse, die CSV-Daten aus unterschiedlichsten Quellen von Personen deserialisieren kann. Was hindert uns nun daran, einen weiteren Deserializer zu bauen, der aus Dateien deserialisiert? Beispiel: public class PersonCsvFileDeserializer : IDeserializer<Person> { private string fileName; public PersonCsvFileDeserializer(string fileName) { this.fileName = fileName; } public IEnumerable<Person> Deserialize() { using (TextReader reader = File.OpenText(fileName)) { PersonCsvDeserializer deserializer = new PersonCsvDeserializer(reader); return deserializer.Deserialize(); } } } Das using wurde nach PersonCsvFileDeserializer und somit eine ebene tiefer verschoben. Wenn du Dependecy Injection verstanden hast, dann würde dir auffallen, dass die Zeile PersonCsvDeserializer deserializer = new PersonCsvDeserializer(reader); eigentlich böse ist, da es eine Abhängigkeit darstellt, die wiederum in den Konstruktor gehört. Ich habe sie aber erst mal hier drinnengelassen, weil das sonst wieder bedeuten würde, dass das using wieder ins Hauptprogramm rein müsste. Eigentlich müsste man sich eine Fabrik-Methode ausdenken, die den PersonCsvFileDeserializer zusammenbaut. Die habe ich hier aber weggelassen. Die kannst du dir ja ausdenken. Das Hauptprogramm würde dann so aussehen: static void Main(string[] args) { string sourcePath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\blabla"; IEnumerable<string> fileNames = Directory.GetFiles(rootPath, "*.csv"); foreach(string fileName in fileNames) { PersonCsvFileDeserializer deserializer = new PersonCsvFileDeserializer(fileName); IEnumerable<Person> persons = deserializer.Deserialize(); foreach (Person person in persons) { // ... } } } Das wäre doch schon wieder ein Schritt übersichtlicher. Wie du also siehst, haben wir allein nur für das Einlesen von den CSV-Dateien drei Klassen: Person PersonCsvDeserializer PersonCsvFileDeserializer und ein Interface: IDeserializer<T> geschrieben. Man braucht also kein mega großes Projekt, um mehrere Klassen zu schreiben. Es reicht auch schon was ganz einfaches. Man sollte sich immer bewusst machen, dass Klassen immer nur eine Aufgabe machen sollten und Methoden Teilaspekte dieser Aufgabe sind und sie sollten auch nicht mehr machen, als eine Sache. Es macht auch nichts, wenn man zum Anfang Spagetticode schreibt und diesen später nach und nach einem Refactoring unterzieht. Niemand ist perfekt und niemand schreibt perfekten Code. Man fängt also immer erst mal an und arbeitet sich Schritt für Schritt an eine geeignete und saubere Lösung. Selbst meine Lösung ist mit Sicherheit nicht perfekt und ich habe auch nicht die Weisheit mit Löffeln gefressen. Wenn du mein Beitrag richtig verfolgt haben solltest, hast du vielleicht auch gemerkt, dass ich erst mal eine Lösung geschrieben habe und sie dann nach und nach verfeinert und verbessert habe. Das Wissen kommt erst mit Erfahrung und Erfahrung sammelt man nur, indem man es ausprobiert und darüber mit anderen diskutiert. Also trau dich. So, das reicht auch fürs erste. Ich denke, das ist erst mal genug Input.
-
C# Programmabsturz IO-Exception
Whiz-zarD antwortete auf Tician's Frage in Anwendungsentwickler und Programmierer
Glaube mir mal, deine Probleme beruhen darauf, dass der Code so schlecht geschrieben wurde. Es ist äußerst schwierig, dort den Überblick zu behalten. Du sagst ja selber, dass du die Kommentare schreibst, um dich daran zu erinnern, was das soll aber so etwas brauchst du bei einem gut strukturierten Code nicht. Es ist ein trugschluss, wenn man meint, man spart Zeit, wenn man den Code hinfrickelt. Ja, mag sein, dass der initiale Aufwand geringer ist aber der Aufwand kommt bei der Fehlersuche und momentan raubt doch die Fehlersuche viel Zeit. Wenn dir das schon bei so einem kleinen Programm nicht der Sinn von Klassen erschließt, dann wohl gar nicht. Ich habe dir schon Beispiele genannt, wie man hier vier Klassen designen kann, wenn du das dann immer noch nicht verstehst, wann dann? Entweder du willst es lernen oder nicht. Wenn du es lernen willst, dann probiere es einfach aus. Versperr dich doch nicht.