Vorweg muss ich sagen, dass ich auch "nur" Hobbyprogrammierer bin und keinen Studienabschluss habe; aber ich habe mich schon länger mit C#/.NET beschäftigt und hätte den Code im Buch in verständlicherer und klarerer Form schreiben können. Das gibt mir zu denken.
Das Buch erhält von mir für die Originalität und das vermittelte Wissen aus anderen Gebieten und auch, da die Projekte an sich lustig/interessant sind, noch drei Sterne.
Sachen wie Wegfindung (Labyrinth), Graphik (DAX-Diagramm) und Spiele-Logik (Poker) wollte ich mir immer schon mal ansehen. Den Untertitel "Grundkenntnisse in C# vorausgesetzt" kann ich nur doppelt unterstreichen! Vielleicht sogar ein paar Kenntnisse mehr, um die Fehlgriffe des Autors auszubügeln. Fühlen Sie/fühlt Euch auf jeden Fall angespornt, es besser zu machen!
Laut Einbandtext beschäftigt sich Herr Klappert schon über 10 Jahre mit Programmiersprachen als Freiberufler; allerdings dürfte er noch nicht lange mit C#/.NET arbeiten. Er scheint mit Englisch auch das eine oder andere Problem zu haben. Teilweise mischt er englische mit deutschen Bezeichnern und die Namensvergabe ist alles andere als verständnisfördernd und klar.
Er entschuldigt sich zwar im Vorspann für den Mangel an "Ästhetik" im Code - allerdings wird auch nicht von ihm erwartet, dass dieses Buch mit Entwurfsmustern und Glanzstücken der Software-Architektur gespickt ist. Was man allerdings sehr wohl erwarten und voraussetzen können muss, ist eine saubere und verständliche Namensgebung von Variablen, Funktionen und Klassen! Schon allein die Vorbildfunktion wäre wichtig. Doch hier versagt der Autor leider völlig. Möglicherweise ist er von den anderen Programmiersprachen schon zu sehr "vergiftet" in seinem Stil. Jedenfalls hat er sich sicher noch nie mit einem .NET Coding Guide beschäftigt. Die Empfehlungen Microsofts sind sehr klar, Camel Casing ("eineVariable") und Pascal Casing ("EineFunktion", "EinProperty") zu verwenden. Der Unterstrich (_) ist bis auf den Sonderfall der EventHandler verpönt. Außerdem gibt es Empfehlungen, wie und wo man Adjektive, Verben und Nomen verwenden soll.
Beispiele für Variablen-, Funktions-, Klassen-Namen des Autors - als Kommentar füge ich am Ende der Zeile ein, was gemeint ist bzw. ich mir dabei denke:
private DelayTime delTime = new DelayTime(); // "del" klingt zu sehr nach "delete", warum nicht "delayTime" oder besser timeDelayer als Instant von TimeDelayer?
private StopTimer stTimer = new StopTimer(); // why not "stopTimer"?
private Creating dr = new Creating(); // warum Gerundium? Nomen verwenden! "Creation"; aber wovon? Warum nicht gleich in Richtung "StarFactory" oder "StarGenerator" denken? Und "dr" ist bitte was genau?
private Timer starsTimer = new Timer(); // ok - vielleicht starTimer, aber siehe nächste Zeile ...
private Timer animateTimer = new Timer(); // wie wär's mit "animationTimer"? Der Timer selbst wird ja mal sicher nicht animiert ... Außerdem wäre animate als Verb ein Klassiker für einen Methodennamen, nicht für eine Variable.
private Random sr = new Random(); // was soll das "s"? Warum nicht "random" oder "rand"?
private int cindex; // Sie haben sicher den vollen Durchblick, dass der Autor etwas wie "private int alphaValue;" meint
private int index; // auch völlig klar, "private int scaleValue;"
void Background_Paint(Color bc) { ... } // void PaintBackground(Color backgroundColor) { ... }
void Gitter_Paint(int ind, int cin, Color co) { ... } // void PaintGrid(int scale, int alphaValue, Color color) { ... }
static System.Windows.Forms.Timer static_clockTimer = new ...
static System.Windows.Forms.Timer clockTimer = new ... // und wo ist nun erkennbar, wofür der "static_clockTimer" und wofür der "clockTimer" steht? Nomenklatur?
private void cTime_Load(object sender, EventArgs e) { ... } // cTime ist jetzt was?
private Label static_clocklabel; // static verwirrt zusätzlich im Sinne von Variablenspezifizierer "static", und was genau gemeint sein soll sei dahingestellt ... Labels setzen ja in sich schon die Verwendung als statischen Text voraus, muss man das extra betonen?
public void retardingStars() { ... } // ich habe zuerst an retardiert, also geistig zurückgeblieben gedacht - wobei retardieren tatsächlich auch verzögern heißt, nur fühlt sich das hier grammatikalisch falsch an; warum nicht einfach "SetDelayedStars" oder - was die Methode eigentlich tut - "SetStarTimer"?
Die Liste ließe sich beliebig mit solch Kreationen fortsetzen.
Zuletzt sind da leider auch noch peinliche Fehler, die im Buch/Code immer wieder wiederholt werden:
* Timer: Der Autor spricht immer von System.Threading.Timer, gemeint sollte aber immer System.Windows.Forms.Timer sein! In .NET gibt es drei verschiedene Timer-Klassen, alle mit speziellen Einsatzgebieten!
* int xy = Convert.ToInt16(...): Der Autor verwendet immer die Convert.ToInt16()-Funktion, wenn er in einen int casten will. Man sollte aber als .NET-Programmierer wissen, dass ein int in .NET einem System.Int32 entspricht! Es ist lange her, dass ints in C++-Compilern 2 Byte (16 Bit) waren. Somit drückt er selber immer auf die Performance, weil er damit noch einen impliziten Cast erzwingt.
Merkwürdig sind auch gewisse Sager in der .NET-Einführung. So zieht er im Vorspann über den .NET Garbage Collector her und redet von der Nicht-Eignung für Echtzeitsysteme - und schlägt dann gegen Ende des Kapitels wieder versöhnliche Töne an. Ob ein Anfänger weiß, was er damit ausdrücken wollte oder ob nun .NET doch was Schlechtes ist? Herr Klappert hat zwar mit der Aussage recht, dass Entwickler auch in der Lage sein sollten, Objekte, die sie erstellen, selber wieder aufzuräumen - nur die Praxis und die ganzen Sicherheitsprobleme der Vergangenheit haben ja ganz deutlich gezeigt, dass Memory Leaks ein großes Problem sind - auch in Hinblick auf sicheren Code und Schadsoftware. Menschen verlieren nun mal mit zunehmender Komplexität die Übersicht. Und wenn Microsoft sogar seinen Exchange Server 2007 in .NET programmiert und mit .NET 4 die Parallel-Bibliothek für Mehrkernrechner eingeführt wurde, sollte man doch mal aussprechen, dass .NET nichts "Billiges" oder "Stümperhaftes" ist und die Performance für die meisten Anwendungsfälle mehr als ausreichen wird. Technologien wie NGEN, die die Performance erhöhen, bleiben unerwähnt.
Klar, einen Gerätetreiber wird keiner in .NET schreiben, aber das ist auch nicht der Punkt des Buchs. Er hätte in wenigen einfachen Sätzen darstellen können, dass der GC etwas Gutes/Wichtiges ist, aber es halt Sonderfälle gibt, die entweder eine entsprechende Behandlung im Code erfordern oder den Wechsel zu einer hardwarenäheren Sprache voraussetzen. Punkt.
Somit bleibt ein sehr gemischtes Gefühl zurück, jedenfalls mussten diese Dinge mal gesagt werden. Wer dieses Buch redigiert hat weiß ich nicht, aber ich hoffe mal auf einen Qualitätssprung in der zweiten Auflage - der Gedanke hinter dem Buch ist ja ein sehr toller, nur die Umsetzung ist mangelhaft!
Nachdem das jetzt raus ist, kann ich entspannter weiterprogrammieren - ich bin gerade in Kapitel 3. Nun wissen Sie bzw. wisst Ihr zumindest, was Sie/Euch erwartet - es muss jeder selber entscheiden, ob er die "Herausforderung" annimmt oder lieber auf andere Literatur zurückgreift. Allerdings gibt es derzeit kaum Literatur mit "for fun"-Projekten in .NET/C#. Ich kenne außer diesem nur ein zweites Buch, in Englisch, das sich diesem Thema widmet. Ich habe es aber noch nicht gelesen und Werbung ist ja glaube ich in Rezensionen sowieso verboten.