°Junoland.de HOME     www.Junoland.de     Valid HTML 4.01 Transitional     (c) Copyright 2008 °Andreas Klotz, Cologne, Germany [upd.Oct.2008]     AKL@Junoland.de

C# Buch-Besprechung - 10 deutsche Titel in der Kritik

Folgende C#-Bücher möchte ich ausführlich und kritisch besprechen:

NrAutorTitelSeitenEURVerlagJahrISBN
D01 Louis / Strasser C# in 21 Tagen 844 44,95 Markt + Technik 2002 3-8272-6069-8
D02 Armin Hanisch Go To C# 534 39,95 Addison Wesley 2002 3-8273-1932-3
D03 Jürgen Bayer C# Nitty Gritty 448 12,95 Addison Wesley 2002 3-8273-1856-4
D04 Frank Eller C# Lernen 322 24,95? Addison Wesley 2001 3-8273-1784-3
D05 Moses / Nowak C# Progammieren unter .Net 645 49,95 Franzis' 2002 3-7723-7224-4
D06 Andrew Troelsen C# und die .Net-Plattform 928 50,00 mitp 2002 3-8266-0833-X
D07 Golo Haas Guide To C Sharp . . www.guidetocsharp.de 2002 .
D08 Erler / Ricken C# - Das Einsteigerseminar 425 ? moderne industrie Buch 2001 3-8266-7169-4
D09 Eric Gunnerson C Sharp - Die neue Sprache . . www.galileocomputing.de 2001 .
D10 Helma Spona C# Der leichte Einstieg 384 9,95 Markt + Technik 2002 3-8272-6399-9

Inzwischen (6 Jahre später) ist mein Favorit das Buch, das bei Galileo online zu lesen und auch komplett zum kostenlosen Download bereitsteht:
Visual C# 2008 von Andreas Kuehnel
Ich denke, dass der Autor meinem Ideal eines guten Fachbuch-Schreibers am nächsten kommt.    [Gute Schreibe]
Und das sage ich nicht etwa, weil es das Buch für 'umme' gibt! Ich komme bei meiner Suche nach C#-Funktionen immer wieder über Google auf dieses Buch zurück und finde dort meistens auch immer die besten deutschsprachigen Erklärungen.



Digital English: Diese Bücher werden nicht besprochen - Wertung von ++ bis --
Um es kurz zu machen:

Ich empfehle aus tiefer Überzeugung genau 2 Bücher, und zwar die von

Louis/Strasser und Hanisch !

Man erwartet von einem Buch über ein schwieriges Thema - und wenn C# und OOP nicht kompliziert sind, was soll dann überhaupt noch kompliziert sein - von einem solchen Buch erwartet man ja eigentlich nur, dass man etwas geduldig erklärt bekommt. Und wenn dies auf natürliche Art gelingt, dann gibt es ja eigentlich keinen Anlass zur Verwunderung. Erst wenn man an den dunklen Ansätzen anderer Autoren verzweifelt, erkennt man den Rang von solchen Büchern. Viele Eigenarten von C# und der objektorientierten Programmierung habe ich gerade bei eben diesen beiden zum ersten Mal verstanden.

Der Umfang der behandelten Themen ist m.E. gerade richtig bemessen: Alles, was OOP betrifft gut erklärt und zusätzlich eine Einführung in die Programmierung der grafischen Benutzeroberfläche und andere C#-spezifische Themen - was will man mehr? Der große Rest besteht aus Darstellung der wichtigsten Funktionen aus der unüberschaubaren Zahl von Bibliotheken.

Louis/Strasser steht wegen der noch größeren Menge des behandelten Stoffs an der Spitze. Sonst sind beide Werke als ebenbürtig anzusehen. Dem einen oder anderen wird die Fassung von Hanisch gerade wegen ihrer größerern Straffung vorteilhafter erscheinen. Egal, welches man wählt - mit beiden liegt man richtig.



Die Ansätze von Bayer und von Eller sind auch okay, bringen die Dinge aber nicht immer so klar 'rüber. Wenn man das Preis-Leistungsverhältnis mit in Betracht ziehen würde (was ich aber bewusst nicht tue), stünden beide sicherlich an der Spitze.

Als Zweit-Buch für Dinge, die in den beiden erstgenannten Werken nicht behandelt werden, würde ich dann eines der folgenden beiden empfehlen: Moses/Nowak und Troelsen.

Im Moses/Nowak-Buch sind einige fachspezifische Sachen zu finden, die sonst nirgenwo anders stehen, zB ein Vergleich C# zu Managed C++ mit Stoppuhr. Didaktisch m.E. leider nur zeitweise gut, schade eigentlich. Nowak als Co-Autor, der zu ca. 80% das eigentliche Buch bestreitet, hat eben sehr eigenwillige Ansätze, im Guten wie im Schlechten; er scheint mir auch einer der wenigen Autoren zu sein, die zu einem kritisch-vergleichenden überblick über Progammier-Techniken fähig sind.

Im Troelsen-Buch sind ebenfalls viele Dinge zu finden, die weit über ein Anfänger-Buch hinaus gehen. Sein Stil ist mir persönlich aber nicht eingängig genug, vielleicht haben andere Leser kein Problem damit. Zum Teil mage es auch an der schlechten übersetzung und dem dürftigen Stichwortverzeichnis liegen. 928 sehr eng bedruckte Seiten entsprechen ungefähr 1500 Seiten Normaldruck! Es wird also eine wirklich breite Themengruppe abgehandelt.



Haas bringt eigentlich viel zu wenig; was er bringt, macht er aber halbwegs gut, auch wenn mir das ewige Beispiel der irrealen Zahlen nicht eingängig genug ist. Scheint mir außerdem etwas unkritisch und zu sehr auf die Möglichkeiten von C# beschränkt. Ist aber ein sehr sympatischer Ansatz eines hoffnungsvollen jungen Mannes und für viele Leute die erste Anlaufstelle für das Thema C#, weil im Netz gratis und ohne Umschweife verfügbar.



Nicht so gut bis regelrecht schlecht finde ich die Bücher von Erler/Ricken, Gunnerson und Spona:

Erler / Ricken könnten ihren Stoff auch auf der Hälfte der Seiten ausdrucken, wenn sie eine nicht so sperrige Schriftart verwendeten. Vom Konzept her eben mehr ein schneller Ritt in medias res anhand von zwei, drei eingängigen Beispielen, mannchmal eingängig, oft aber zu schludrig.

Gunnerson gliedert zwar klar, ich verstehe ihn aber dennoch nur recht verschwommen. Man schaue nur einmal in das Kapitel 20, Indizierer:
"Gelegentlich ist es hilfreich, ein Objekt so indizieren zu können, als handele es sich um ein Objekt. Dies kann erreicht werden, indem ein Indizierer für das Objekt geschrieben wird. Diesen kann man sich wie ein »schlaues« Array vorstellen." ... - Hä? alles klar? - Um mit Marc Cohen im Song "Walkin' in Memphis" zu antworten: Do I really feel the way I feel???

Spona schrieb in meinen Augen das mit Abstand schlechteste, was ich in die Finger bekommen habe, sorry! Kratzt sehr an der Oberfläche. Schreitet sehr schnell zur grafischen Benutzeroberfläche und erklärt das meiste en passant und extrem unvollständig. Ihr Ansatz ist einfach zu pragmatisch, so sympatisch dem einen oder anderen dies zu Beginn erscheinen mag, dass hier weniger doziert wird, um so schneller mit der GUI zu hantieren.



Näheres zur Begründung meiner Kritik ist in den Kommentaren zu den Textpassagen zum Thema 'static' zu finden. Ich habe in allen Büchern nach Erklärungen zu Static und zu Schleifen gesucht und verglichen, wobei die Schleifen-Passagen unkommentiert geblieben sind.

Aachen/ Köln, im Nov.2003 Andreas Klotz





D01 - Static    ↑    Louis / Strasser : C# in 21 Tagen

S.287 Felder
"Felder sind die Datenelemente der Klasse. Definiert werden sie durch Angabe eines Zugriffsspezifizierers, des Datentyps und des Feldnamens.

Ihr Gültigkeitsbereich ist die Klasse selbst, d.h. alle Methoden der Klasse (einschließlich Konstruktor, Destruktor, Eigenschaften) können auf die Felder zugreifen.

Bei der Instanzbildung bekommt das erzeugte Objekt von jedem Feld der Klasse eine eigene Kopie. Die Lebensdauer eines Felds ist daher gleich der Lebensdauer des Objekts, zu dem es gehört."


Okay, ein wenig knapp für erste, wird aber später noch genauer auseinander gesetzt.

Initialisierung
Der übliche Ort zur Initialisierung von Feldern ist der Konstruktor:"
  class CDemo
  {
    int feld1;
    internal CDemo()
    {
      feld1 = 12;
    }
	...	
"Allerdings handelt es sich hierbei technisch gesehen gar nicht um eine Initialisierung, son- dern lediglich um die Zuweisung eines Anfangswerts. Initialisiert wurde das Feld nämlich bereits bei seiner Erzeugung (als es im Speicherbereich des Objekts angelegt wurde). Der Compiler weist den Feldern dabei ihren Standardwert zu (beispielsweise O für 1 nt oder double, false für bool). Wenn Sie möchten, dass ein Feld mit einem anderen Wert initiali- siert wird, müssen Sie diesen bei der Felddefinition angeben:"
  class CDemo 
  {
    int feld1 = 122;
    internal CDemo() 
    {
      Console.WriteLine(feld1);
    }
  ...
"Die echte Initialisierung ist schneller als die Zuweisung eines Anfangswerts im Konstruk- tor, aber auch weniger flexibel, da im Wesentlichen nur Literale zugewiesen werden kön- nen."
Literale? Also manuell eingetippt und nicht übernommen von einer anderen Variablen.

...

S.290 Statische Felder
"Statische Felder sind Felder, die mit dem Schlüsselwort static deklariert wurden. Statische Felder existieren lediglich als Felder ihrer Klasse. Nicht-statische Felder werden bei der Objekterzeugung kopiert, damit jedes erzeugte Objekt eine eigene Kopie des Feldes erhält. Von einem statischen Feld einer Klasse gibt es allerdings nur eine einzige Kopie. Statische Felder stellen daher eine Möglichkeit dar, mit der die einzelnen Objekte einer Klasse untereinander Daten und Informationen austauschen können."
Endlich mal ein Autorengespann, das an mehr als das bloße Gezählt-werden denkt!
"Statische Felder werden immer über den Namen der Klasse angesprochen. Statische Fel- der können daher benutzt werden, ohne dass ein Objekt der Klasse erzeugt wurde:"...
Nicht 'können' - 'müssen' ist richtig!

(es folgt ein Beispiel)
"Schließlich sind statische Felder die einzigen Felder, auf die statische Methoden zugreifen können."
...
"Statische Felder sind beileibe nicht nur für die Implementierung von Klassen interessant, die reine Sammlungen statischer Methoden darstellen. Auch das Mischen statischer und nicht-statischer Klassenelemente ist möglich. Das folgende Beispiel nutzt ein statisches Feld, um mitzuzählen, wie viele Objekte der Klasse erzeugt wurden:"
...

Aha, Mischen ist möglich. Diesen ausdrücklichen Hinweis lasse ich mir gerne gefallen.

...

Variablenterminologie
"Felder sind letztlich nichts anderes als Variablen, die im Gültigkeitsbereich einer Klasse definiert wurden. Insgesamt haben Sie nun also vier verschiedene Kategorien von Variab- len kennen gelernt.

# lokale Variable : Variable, die innerhalb einer Methode deklariert wird

# Instanzvariable : nicht-statisches Feld, von dem jedes erzeugte Objekt (Instanz) der Klasse eine eigene Kopie erhält

# Klassenvariable : statisches Feld, von dem es stets nur eine Kopie gibt

# Objektvariable : eine Variable, die eine Referenz auf ein Klassenobjekt im Speicher enthält"
Eine sehr schöne Aufstellung, danke, ihr sprecht meine Sprache!

Nebenbei gesagt, ich habe die einfache Tatsache, dass es ja auch noch einfach lokale Variablen innerhalb von Methoden gibt, quasi rein temporäre Hilfsvariablen ohne Bezug zu Klasse oder Objekt, nirgendwo anders als hier erwähnt gefunden. Man denke z.B. an die einfache Zählvariable, die erst in der for-Schleife deklariert wird...

...

S.292 Methoden

...

S.296 Statische Methoden
"Statische Methoden werden ebenso wie die statischen Felder durch Voranstellung des Schlüsselwortes static definiert und nur über den Klassennamen aufgerufen.

Statische Methoden können nur auf statische Felder einer Klasse zugreifen. Nach den Ausführungen des vorangehenden Abschnittes sollte auch klar sein, warum. Statische Methoden verfügen über keinen this-Verweis."
Naja, wie soll das denn auch gehen? Auf welches Objekt soll die static Methode denn dann bezogen werden, frage ich mich. Und deshlab gibt es eben auch kein 'this' für diese Methoden; bitte so herum und nicht anders, oder bin ich hier derjenige, der die Dinge zu verwirrt sieht?
Statische Methoden und private Konstruktoren

"Statische Methoden werden meist zur Implementierung von Funktionensammlungen ver- wendet. Es ist aber auch möglich, in einer Klasse, die echte Objekte beschreibt, normale und statische Methoden gemeinsam zu verwenden.

Schauen Sie sich noch einmal das Programm StatischeFelder.cs aus Abschnitt »Statische Felder« an. Dort wurde ein statisches Feld zum Zählen der Gespenster-Objekte verwendet. Das Beispiel hatte aber keine sinnvolle Verwendung für den Zähler. In dem nachfolgen- den Beispiel soll der Zähler dazu genutzt werden, die maximale Anzahl Gespenster auf 3 zu begrenzen. Dies wird mit Hilfe eines Tricks erreicht, der darin besteht, den einzigen Konstruktor der Klasse als private zu deklarieren und die Objekterzeugung durch eine sta- tische Methode zu kontrollieren."
Na gut, wird also nur einmalig vor Gebrauch der Klasse initialisiert. Hätte man vielleicht auch ausdrücklicher sagen sollen, finde ich.





D01 - Loop.   ↑    Louis / Strasser : C# in 21 Tagen

S.187
"Sollen die Anweisungen einer while-Schleife beim ersten Aufruf ausgeführt werden, muss die Bedingung beim ersten Aufruf der while-Schleife erfüllt sein. Ist das nicht der Fall, wird der komplette Anweisungsblock der while-Schleife ignoriert. Sollte aber eine Schleife, die mit dem Schlüsselwort while ausgeführt werden soll, mindestens einmal durchlaufen wer- den, benötigen wir eine do-while-Schleife. Diese Art der Schleife bezeichnet man auch als fußgesteuerte Schleife, da die Bedingung erst am Ende des Anweisungsblocks der while- Schleife überprüft wird.

Die Syntax einer do-while-Schleife sieht folgendermaßen aus:
	do
    Anweisung;
  while(Ausdruck);
oder:
  do
  {
     Anweisung(en);
  }
  while(Ausdruck);
Die Syntax der do-while-Schleife verdeutlicht den Ablauf der überprüfung. Bevor der Aus- druck überprüft wird, werden die Anweisungen ausgeführt. Auffallend ist auch das Semiko- lon im Schleifenfuß. Dieses Semikolon darf unter keine Umständen fehlen, da sonst der Compiler eine Fehlermeldung erzeugt. Programmtechnisch stellt der Schleifenfuß eine Leeranweisung dar, die mit dem Schlüsselwort do verknüpft ist.
  using System;
  class CDoWhile
  {
    static void Main(string[] args)
    {
      int iRef = 5;
      while (iRef != 5)
         Console.WriteLine("(while) Wert iRef: {0}" ,iRef):

      do
           Console.WriteLine("(do-while) Wert iRef: {0}" ,iRef):
       while (iRef != 5); 

        Console.ReadLine();
     }
  }
In der Zeile 9 wird eine Variable iRef vom Typ Integer deklariert und mit dem Wert 5 initialisiert. Die Zeile 11 verwendet die while-Schleife, um den Wert in der Konsole auszugeben. Dazu kommt es aber nicht, da es sich um eine kopfge- steuerte Schleife handelt und die Bedingung des Ausdrucks der while-Schleite nicht erfüllt wird. Ist es aber erwünscht, die Anweisungen, die im Anweisungs- block einer while-Schleife stehen, mindestens einmal zu durchlauten, muss man auf eine do-while-Schleife ausweichen. Die Ausgabe in Zeile 15 wird aus- geführt, bevor die while-Schleite die Bedingung ihres Ausdrucks überprüft."






D02 - Static    ↑    Armin Hanisch : Go to C#



7.7 Statische Klassenmitglieder
"Jede Instanz einer Klasse besitzt ebenfall ihre eigene Instanz der Mit- glieder dieser Klasse. Dazu ein Beispiel: Im letzten Abschnitt habe ich Ihnen die Klasse Konto vorgestellt. Wird mit new aus dieser Klasse eine Instanz erzeugt, besitzt jede Instanz eine eigene Kopie des Feldes fsaldo. Schließlich hätten Sie etwas dagegen, dass eine Buchung auf ein Konto alle anderen Instanzen Ihrer Geschäftskonten auf den gleichen Wert setzt, es sei denn, Sie haben gerade ein völlg revolutionäres Buchhaltungskonzept erfunden ... "
Mitglieder? Sind damit nicht-statische Elemente einer Klasse gemeint, wie zB Objekt-Variablen? Ist zwar mit gutem Willen noch gerade zu vetehen, könnte man aber leichter fasslich gestalten, etwa so:

'Objekte, die nach dem Bauplan einer Klasse erstellt werden, nennt man auch Instanzen dieser Klasse. Sieht der Bauplan vor, dass für jedes Objekt der Wert einer bestimmten Eigenschaft in Form einer Variablen festgehalten werden soll, wird also für jedes Objekt auch der zugehörige Platz reserviert.'
"Bei bestimmten Gelegenheiten macht es aber keinen Sinn, wenn Daten oder Code für jede Instanz einer Klasse gesondert angelegt werden. Bei unserer Konto-Klasse könnte die Notwendigkeit einer Euro-Umrech- nung auftreten, daher solle ich wohl besser irgendwo in der Klasse die offiziellen Umrechnungskurse für die einzelnen Währungen in der Klasse unterbringen. Die Werte sind aber nun wirklich für jede Instanz der Klasse gleich und müssen daher eigentlich nur einmal gespeichert werden. Diese Daten gehören logisch gesehen also eher zur gesamten Klasse als zu einer bestimmten Instanz."
Okay, das treffende Beispiel versöhnt mich wieder.

7.7.1 Das Schlüsselwort static
"Solche Mitglieder einer Klasse werden als statische Mitglieder (static members) bezeichnet. Einige andere Programmiersprachen bezeichnen solche Konstruktionen auch als Klassenfunktionen (classfunctions), was sprachlich beinahe besser passt. Ein weiteres Beispiel ist der Startpunkt jeder .NET-Anwendung in C#:

public static void Main() { }

Auch dieser Code muss nur einmal im Speicher vorhanden sein, unab- hängig davon, wie viele Instanzen der Klasse ich erzeuge. Wie Sie erkennen, wird bei der Deklaration eines static einfach dieses Schlüs- selwort nach der Sichtbarkeit und vor dem Datentyp angegeben. "
...

7.7.2 Zugriff auf statische Klassenmitglieder

"Wenn ein static zur Klasse und nicht zu einer Instanz (einem Objekt) gehört, dann kann auf dieses Feld oder diese Methode auch nur über die Klasse zugegriffen werden."
Ja, aber auf normale Objekt-Eigenschaften greift man doch - zumindest indirekt - ebenfalls letzten Endes über die Klassen-Bezeichnung zu! Indem man nämlich bei der Initialisierung der Objekte mit new sagt, von welcher Sorte, sprich von welcher Klasse, das Objekt sein soll. Besser wäre es also zu sagen: ' ... auf dieses Feld oder diese Methode nur über die Nennung des Klassennamens direkt zugegriffen werden - also ohne Nennung eines Objekts dieser Klasse'.

...

7.7.3 Statische Konstruktoren
"Sie können für eine Klasse auch einen statischen Konstruktor definie- ren. Dieser kann beispielsweise zur Berechnung von statischen Feldern dienen, welche als readonly deklariert sind, weil der Wert zur Zeit der Kompilierung noch nicht feststand.
  class Machwas 
  {
  public Machwas()
    {
      // der normale konstruktor
    }

  // keine modifikatoren zulassig
  static Machwas()
    {
       // der statische konstruktor
    }
  }
"Nachdem statische Konstruktoren zur Klasse gehören, sind bei ihnen Modifikatoren für die Sichtbarkeit nicht zulässig. Die Benutzung von statischen Konstruktoren bietet sich für einmalige Initialisierungen an, die für die gesamte Klasse und nicht für einzelne Instanzen dieser Klasse durchgeführt werden sollen."
Gut, dass der Autor diese einleuchtende Möglichkeit erwähnt. Habe ich noch nicht all zu oft in anderen Büchern zum Thema vorgefunden.
"Die .NET-Laufzeitumgebung garantiert, dass ein statischer Konstruktor nach dem Start der Anwendung und vor der Erstellung der Instanz die- ser Klasse ausgeführt wird, aber nicht mehr. Der Aufruf kann zeitlich also von der tatsächlichen Erstellung einer Instanz dieser Klasse deutlich getrennt sein."
Aha, so kann man sich das Ganze also auch noch 'aus Compiler-Sicht' vorstellen, warum nicht. Aber kann es nicht sein, dass der Aufruf nicht unbestimmt irgendwann zwischen A und B stattfindt, sondern ganz genau vor dem ersten Aufruf eines Elements von B? Dies sind Kleinigkeiten, könnte sein, dass ich mich irre.





D02 - Loop    ↑    Armin Hanisch : Go to C#



S.142

Bedingte Schleifen - DO & WHILE

"Wenn Sie in C# eine Anweisung oder einen Block mehrmals wieder- holt ausführen lassen möchten, haben Sie zwei Möglichkeiten, abhän- gig davon, ob Sie bereits wissen, wie oft diese Wiederholung gesche- hen soll. Fall ja, verwenden Sie die for-Schleife, fall nicht, dann benutzen Sie entweder do oder while.

while arbeitet so, wie Sie das wahrscheinlich auch von anderen Spra- chen her kennen: ein Ausdruck wird zu einem bool-Wert evaluiert und falls dieser true ergibt, wird die Anweisung (eine einzelne Anweisung oder ein Block) ausgeführt. Anschließend wiederholt sich das Ganze, bis die Auswertung des Ausdrucks den Wert false ergibt.
string s;
while ( (s = Console.ReadLine() != null )
  // ausgeben, bis alle Zellen gelesen wurden
  Console.WriteLine(s);
Lesern aus der C- und Java-Ecke wird dieser Code wahrscheinlich nur ein Gähnen entlocken, für VB-Umsteiger möchte ich an dieser Stelle doch noch einmal den Ausdruck hinter while erläutern, da dieses Kon- zept in C-ähnlichen Sprachen üblich ist.

Nach while steht ein Ausdruck, der einen bool-Wert ergeben muss. Die Zuweisung von s = Console.ReadLine() liefert entweder den String aus der Eingabe oder null, falls keine Zeilen mehr zur Verfü- gung stehen (da das Ende der Datei erreicht ist). Dieses Ergebnis wird mit dem Literal null verglichen und liefert damit einen bool-Wert. Sormt haben Sie eine Zuweisung und einen Vergleich in einem Aus- druck erreicht. Diese Art der Codierung werden Sie in C#-Code noch häufig sehen.

do-Schleifen funktionieren ähnlich, arbeiten allerdings als so genannte annehmende Schleifen, d. h. zuerst wird der Schleifenkörper einmal aus- geführt, dann wird die Bedingung getestet. Diese Art der Wiederho- lung eignet sich vor allem dann, wenn Sie eine Aktion ausführen möchten, welche selbst erst die Bedingung testbar macht. Ein Beispiel dafür sind kommandogesteuerte Programme (wie ein ftp-Client), bei denen Sie das Kommando erst dann kennen, wenn es vom Benutzer eingegeben wurde. Sie benötigen also mindestens eine Eingabe, an der Sie die Bedingung testen können.
  string s;
  do {
    s = Console.ReadLine();
    // ausgeben, bis QUIT gelesen wurde
    Console.WriteLine(s);
  }
  while (s != "QUIT" );
"






D03 - Static    ↑    Jürgen Bayer : C# Nitty Gritty

4.8 Statische Klassenelemente
"Normale Eigenschaften und Methoden sind immer einer Instanz ei- ner Klasse zugeordnet.Manchmal besteht aber auch der Bedarf, dass eine Eigenschaft nur ein einziges Mal für alle Instanzen dieser Klasse gespeichert ist oder dass eine Eigenschaft oder Methode ohne Instanz der Klasse verwendet werden kann."
Okay, ist kurz und klar.

4.8.1 Statische Eigenschaften (Klasseneigenschaften)
"Eine statische Eigenschaft ist nur einmal für die Klasse und nicht für jedes Objekt separat gespeichert.Damit können Sie Werte zwischen den einzelnen Instanzen der Klasse austauschen oder die globalen Variablen der strukturierten Programmierung simulieren."
Okay, noch einmal anders zur Verdeutlichung.
"In einer Kontoverwaltung ist z.B.der Kontostand jedem Kontoobjekt separat zugeordnet,der Zinssatz sollte aber für alle Kontoobjekte ge- meinsam gespeichert sein.Diese Eigenschaft sollte statisch sein und wird einfach mit dem Modifizierer static deklariert: "
...

(es folgt das sattsam bekannte Konto-Beispiel, mit public static zinssatz und einer non-static methode zur berechnung der jeweiligen Zinsen eines Kontos, knapp und gut so.)

...
"Alle Methoden (normale und statische) des Objekts können auf stati- sche Eigenschaften zugreifen.Die ZinsenRechnen-Methode des Bei- spiels demonstriert dies.Eine statische Eigenschaft kann auch ohne Instanz einer Klasse gesetzt und geschrieben werden. Geben Sie dazu den Klassennamen als Präfix an " ...
Tja, 'kann auch ohne' ? Wieso 'kann auch' ? Das hört sich irgendwie so an, als wenn es auch mal 'mit' geht, so wie man seinen Kaffee mit oder ohne Milch nehmen kann. Ob da nun eine Instanz ode mehrer existieren oder gar keine - eine static-Eigenschaft steht gänzlich unabhängig von etwaigen Instanzen! (Auch wenn man in ihr Informationen sammeln könnte, die mit diesen Instanzen inhaltlich zusammenhängen).

Globale Daten in statischen Eigenschaften
"In manchen Fällen ist es sinnvoll oder notwendig,Daten so zu verwal- ten,dass diese global im gesamten Programm gelten.Eigentlich sollten solche Daten grundsätzlich (und besonders bei der OOP ver- mieden werden).Globale Daten beinhalten viele potenzielle Fehler- quellen,da jeder Programmteil auf diese Daten zugreifen und diese (eventuell fehlerhaft) verändern kann. Außerdem machen globale Daten ein Programm sehr undurchsichtig. Wenn Sie das Risiko aber eingehen wollen oder müssen, verwenden Sie dazu einfach eine Klasse mit lediglich statischen Eigenschaften:"
...

(es folgt solch ein Beispiel)

...

Dies sind genau die warnenden Worte vor dem unbedenklichen Gebrauch von static, die an Deutlichkeit nichts vermissen lassen! Gut.

4.8.2 Statische Methoden (Klassenmethoden)
"Statische Methoden können - wie statische Eigenschaften - ebenfalls ohne Instanz der Klasse verwendet werden. Diese Methoden verwenden Sie (sehr selten) für Operationen, die sich auf die Klasse und nicht auf einzelne Objekte beziehen"
- wirklich so selten?! - weiter:
"über statische Methoden können Sie beispielsweise die statischen (privaten) Eigenschaften einer Klasse bearbeiten. Ein Beispiel dafür fehlt hier, weil diese Technik doch eher selten eingesetzt wird."
Wieso selten? Verstehe ich nicht! Kommt doch viel öfter mal vor, als die reine Lehre der OOP es vorschreibt, oder?
"Wesentlich häufiger werden statische Methoden eingesetzt,um glo- bale, allgemein anwendbare,Funktionen in das Projekt einzufügen. Das .NET-Framework nutzt solche Methoden sehr häufig.Die Klasse Math besteht z.B.fast ausschließlich aus statischen Methoden. Wenn Sie z.B.in Ihren Projekten häufig verschiedene Maße und Ge- wichte in nationale Einheiten umrechnen müssen, können Sie dazu eine Klasse mit statischen Methoden verwenden"
...
"Die Verwendung statischer Methoden für allgemeine Aufgaben ist wesentlich einfacher,als wenn Sie dazu immer wieder Objekte in- stanzieren müssten.Um eine Methode der Klasse UnitConversion zu verwenden,müssen Sie lediglich den Klassenamen angeben" ...
Ja, ist breit und gut ausgewalzt.

4.8.3 Statische Konstruktoren
"Neben Eigenschaften und Methoden können auch Konstruktoren sta- tisch deklariert werden. Ein statischer Konstruktor wird nur ein einzi- ges Mal aufgerufen, nämlich dann, wenn die erste Instanz der Klasse erzeugt wird. Damit können Sie Initialisierungen vornehmen,die für alle Instanzen der Klasse gelten sollen. Deklarieren Sie diesen Kon- struktor wie einen normalen Konstruktor, lediglich ohne Sichtbar- keits-Modifizierer und mit dem Schlüsselwort static .

Eine Kontoverwaltung könnte z.B.den aktuellen Zinssatz in einem statischen Konstruktor aus einer Datenbank auslesen"
...
"Statische Methoden können nicht auf die normalen (In- stanz-)Eigenschaften einer Klasse zugreifen.Das ist auch logisch, denn diese Eigenschaften werden erst im Speicher angelegt, wenn eine Instanz der Klasse erzeugt wird."
Endlich fällt - wenn auch erst beim Thema static Konstruktoren - das klärende Wort: Man kann also aus static-Methoden nicht auf Instanz-Variablen zugreifen! Das hätte aber auch schon einige Absätze höher untergebracht werden können, denke ich mal.
"Ein statischer Konstruktor darf keinen Modifizierer für die Sichtbar- keit und keine Argumente besitzen.Neben einem statischen Kon- struktor können Sie natürlich auch normale Konstruktoren deklarie- ren. Statische Destruktoren sind übrigens nicht möglich."
Und jetzt ist wieder alles klar für mich.



D03 - Loop    ↑    Jürgen Bayer : C# Nitty Gritty

3.6.3 Die while-Schleife
"Die while -Schleife überprüft die Schleifenbedingung im Kopf und wiederholt die enthaltenen Anweisungen so lange,wie diese Bedin- gung erfüllt ist:
  while (Bedingung )
  {
     Anweisungen
  }
Beachten Sie,dass diese Schleife nicht mit einem Semikolon abge- schlossen werden muss. Das folgende Beispiel zählt eine Variable hoch,solange diese einen Wert kleiner 10 besitzt:
  int i =1;
  while(i <10)
  {
    Console.WriteLine(i);
    i++;
  }
Eine while -Schleife können Sie mit break explizit abbrechen.So kön- nen Sie Schleifen erzeugen,die ihre Bedingung im Körper überprü- fen:
  i =0;
  while (true)
  {
     i++;
     if (i >9)break;
     Console.WriteLine(i);
  }
Solche Schleifen benötigen Sie dann,wenn die Bedingung so kom- plex ist,dass diese nicht im Kopf oder Fuß der Schleife überprüft wer- den kann.

3.6.4 Die do-Schleife

Die do -Schleife überprüft die Bedingung im Fuß:
  do
     Anweisungen
  while (Bedingung );
Im Unterschied zur while -Schleife wird die do -Schleife mindestens einmal durchlaufen,auch wenn die Bedingung zu Anfang der Schleife bereits falsch ist.Das folgende Beispiel lässt den Anwender eine Ant- wort eingeben und schleift solange,bis dieser die »richtige « Antwort eingegeben hat:
  string answer;
  int i =0;
  do
  {
     i++;
     if (i <3)
       Console.Write("Geben Sie die Antwort ein:");
     else
        Console.Write("Geben Sie die Antwort ein "+
        "(Tipp:Die richtige Antwort ist 42):");
  answer =Console.ReadLine();
  }
  while (answer !="42");
Wie eine while -Schleife,können Sie eine do -Schleife explizit mit break abbrechen:
  i =0;
  do
  {
     i++;
     if (i >9)break;
     Console.WriteLine(i);
  }
  while (true);
"






D04 - Static    ↑    Frank Eller : C# Lernen

3.3.7 Statische Methoden/Variablen
"Die statischen Methoden haben wir bereits kennen gelernt, und wir wissen mittlerweile, dass wir für deren Verwendung keine Instanz der Klasse erzeugen müssen. Man sagt auch, die Attribute einer Klasse, die als static deklariert sind, sind ein Bestandteil der Klasse selbst; die anderen Attribute sind nach der Instanziierung Bestandteile des jeweiligen Objekts."
Okay, ist wirklich klar formuliert.
"Das bedeutet auch Folgendes: Wenn mehrere Instanzen einer Klasse erzeugt wurden und in jeder dieser Instanzen wird eine statische Methode aufgerufen, dann ist das immer dieselbe Methode - sie ist nämlich Bestandteil der Klassendefinition selbst und nicht des Objekts. In Abbildung 3.3 wird im Bild dargestellt, wie sich das Ganze verhält."
...

Redundant, aber noch einmal anders formuliert, ebenfalls leicht fasslich. Ich liebe diese Deutlichkeit bei komplizierten Sachverhalten - auch oder gerade wenn mehr Worte verloren werden als nötig.

...

(Abbildung 3.3: Statischer und vererbbarer Bereich)

...

Globale Variablen
"überlegen wir doch einmal, wie es dann mit den Variablen bzw. Feldern der Klasse aussieht. Wenn eine Variable als static deklariert ist, also Bestandteil der Klasse selbst und nicht des aus der Klasse erzeugten Objekts ist, dann müsste diese Variable praktisch global gültig sein - über alle Instanzen hinweg.

Exakt so ist es. Ein Beispiel soll uns das verdeutlichen. Für dieses Beispiel wird ein Fahrzeugverleih angenommen, der sowohl Fahrräder als auch Motorräder als auch Autos verleiht. Der Besitzer will nun immer wissen, wie viele Autos, Fahrräder und Motorräder unterwegs sind. Wir erstellen also eine entsprechende Klasse Fahrzeug , aus der wir dann die entsprechenden benötigten Objekte erstellen können..."
...

(es folgt das Beispiel)

...
"Die Variable anzVerliehen zählt unsere verliehenen Fahrzeuge. Mit den beiden Methoden Ausleihen()und Zurueck(), die beide als public deklariert sind, können Fahrzeuge verliehen werden. Die Methode GetAnzahl()schließlich liefert die Anzahl verliehener Fahrzeuge zurück, denn die Variable anzVerliehen ist ja als private deklariert (Sie erinnern sich: ohne Modifikator wird in Klassen als Standard die Sichtbarkeitsstufe private verwendet).

Damit funktioniert unsere Klasse bereits, wenn wir eine Instanz davon erstellen. Doch nun will der Fahrzeugverleih auch automatisch eine übersicht aller verliehenen Fahrzeuge bekommen. Nichts leichter als das. Wir fügen einfach eine statische Variable hinzu und schon haben wir einen Zähler, der alle verliehenen Fahrzeuge unabhängig vom Typ zählt."
...

(es folgt das erweiterte Beispiel)

...
"Als Letztes wollen wir nun noch eine Methode hinzufügen, mit der wir erfahren können, wie viele Fahrzeuge insgesamt verliehen sind. Wenn wir die statische Variable anzGesamt nämlich veröffentlichen würden, könnte sie innerhalb des Programms geändert werden. Das soll aber nicht erlaubt sein. Also belassen wir es bei der Sichtbarkeitsstufe private und fügen lieber noch eine Methode hinzu, die wir ausnahmsweise ebenfalls statisch machen."
...

(es folgt das noch weiter erweiterte Beispiel)

...
"Innerhalb einer statischen Methode können Sie nur auf lokale und statische Variablen zugreifen. Die anderen Variablen sind erst verfügbar, wenn eine Instanz der Klasse erzeugt wurde, und da das nicht Voraussetzung für den Aufruf einer statischen Methode ist, können Sie die Instanzvariablen auch nicht verwenden."
Naja, das ist ein Hinweis, der gut angebracht ist, könnte aber noch klarer formuliert werden, etwa so:

' Die anderen Variablen sind erst verfügbar, wenn eine Instanz der Klasse erzeugt wurde - wenn diese denn überhaupt instanziert wird. Und da man statische Methoden aufrufen kann, eben auch ohne vorher Objekte zu erzeugen, kann man grundsätzlich nie von einer statischen Methode aus auf Instanz-Variablen zugreifen'
"In C# ist es nicht möglich, 'richtige' globale Variablen zu deklarieren, weil alle Deklarationen innerhalb einer Klasse vorgenommen werden müssen. Ohne Klassen geht es hier nun mal nicht. Durch das Konzept der statischen Variablen haben Sie aber die Möglichkeit, dennoch allgemeingültige Variablen zu erzeugen.

Deklarieren Sie einfach eine Klasse mit Namen G oder Global , in der Sie alle globalen Variablen zusammenfassen. Deklarieren Sie diese als statische Felder und ermöglichen Sie es allen Programmteilen, auf die Klasse zuzugreifen."
Okay, ist klar, aber ein Warnhinweis wäre vielleicht angebracht, dass man auf diese Weise fern ab von jeglicher OOP geraten kann...

...
"Statische Methoden und Variablen sind wie bereits gesagt Bestandteil der Klasse selbst. Das bedeutet, dass auf sie anders zugegriffen werden muss als auf Instanzmethoden bzw. -variablen. Sehen wir uns die folgende Deklaration einmal an"
...
"Die Methode SCompare()ist eine statische Methode, die Methode Compare()eine Instanzmethode, die erst nach der Erzeugung einer Instanz verfügbar ist. Wenn wir nun auf die Methode SCompare()zugreifen wollen, können wir dies nicht über das erzeugte Objekt tun, stattdessen müssen wir den Bezeichner der Klasse verwenden, denn die statische Methode ist kein Bestandteil des Objekts - sie ist ein Bestandteil der Klasse, aus der wir das Objekt erstellt haben."
Okay, noch einmal, warum nicht.

...
"Bei statischen Methoden wie auch bei statischen Variablen muss zur Qualifizierung der Bezeichner der Klasse selbst benutzt werden, da statische Elemente Bestandteil der Klasse und nicht des erzeugten Objekts sind.

Für Objekte gilt, dass über sie nur auf Instanzmethoden bzw. Instanz-variablen zugegriffen werden kann."
Zum ersten Mal wird es etwas wirrer:

'muss zur Qualifizierung der Bezeichner der Klasse selbst benutzt werden' ?

Hä? Warum nicht einfach: Statische Methoden werden direkt per Klassennamen plus Methodennamen aufgerufen, zB MyClass.MyMethode - also ohne Objektbezeichner (mit Obj. sähe das so aus: MyClass.Obj3.MyMethode)....



D04 - Loop    ↑    Frank Eller : C# Lernen

S.164 Die do-while-Schleife
"Auch die do -Schleife (oder do-while -Schleife) ist abhängig von einer Bedingung. Anders als bei der while -Schleife wird hier der Code aber mindestens einmal durchlaufen, weil die Bedingung erst am Ende der Schleife kontrolliert wird, weshalb man auch von einer nicht-abweisenden Schleife spricht. Die Syntax der do -Schleife lautet wie folgt:
  do
  {
    //Anweisungen
  }  while (Bedingung);
Ein Beispiel für die Verwendung einer do -Schleife ist die Berechnung der Quadratwurzel nach Heron. Es handelt sich dabei um ein Annäherungsverfahren, das bereits nach einer kleinen Anzahl an Schritten ein verhältnismäßig genaues Ergebnis liefert.

Heron ging von folgender überlegung aus: Wenn ein Quadrat existiert, dessen Fläche meiner Zahl entspricht, muss die Kantenlänge dieses Quadrats zwangsläufig der Wurzel der Zahl entsprechen. Wenn ich also ein Rechteck nehme, bei dem eine Kante die Länge 1 besitzt und die andere Kante die Länge meiner Zahl hat, so hat dieses Recht-eck auch die gleiche Fläche. Alles, was nun noch zu tun bleibt, ist, das arithmetische Mittel zweier Kanten zu errechnen und daraus ein neues Rechteck zu bilden, bis es sich um ein Quadrat handelt- die errechnete Kantenlänge ist also dann die gesuchte Wurzel.

Das arithmetische Mittel lässt sich leicht berechnen, es handelt sich um eine einfache mathematische Formel. Unter der Annahme, dass ein Rechteck die Seiten a und b hat, die neuen Seitenlängen a' und b' lauten und die Fläche des Rechtecks mit A bezeichnet wird, lässt sich das arithmetische Mittel der Seiten a und b folgendermaßen errechnen:
  a'=(a+b)/2
Die Errechnung der neuen Seite b' erfolgt über die Fläche, die uns ja bekannt ist:
  b'=A/a'
Vorausgesetzt, dass wir eine Genauigkeit festlegen, bei deren Erreichen die Berechnung beendet werden soll, können wir die Wurzel einer Zahl mit einer einfachen do -Schleife berechnen. Im Beispiel steht die Konstante g f ür die Genauigkeit, die für unsere Berechnung gelten soll.
  /*Beispielklasse do-Schleife (Heron)*/
  /*Autor:Frank Eller */
  /*Sprache:C#*/
  using System;
  class Heron
  {
    public double doHeron(double a)
    {
       double A =a;
       double b =1.0;
       const double g =0.0004;
       do
       {
          a =(a+b)/2;
          b =A/a;
       }
       while ((a-b)>g);
       return a;
     }
  }

  class TestClass
  {
    public static void Main()
    {
      double x =0;
      Heron h =new Heron();
      Console.Write("Geben Sie einen Wert ein:");
       x =Console.ReadLine().ToDouble();
      Console.WriteLine("Wurzel von {0}ist {1}",
      x,h.doHeron(x));
    }
  }
"






D05 - Static    ↑    Moses / Nowak :C# Progammieren unter .Net

S.74
"static bedeutet, dass diese Methode nicht auf Objekte aufgerufen wird (hierzu später mehr).
... S.86 Statische Methoden
Dieses Kapitel behandelt so genannte statische Methoden.

Die statischen Methoden von C# sind vergleichbar mit den Funktionen von C (bzw. mit den statischen Memberfünktionen von C++). Es handelt sich um Methoden, die unabhängig von Objekten aufgerufen werden können (Objekte werden erst im nächsten Kapitel behandelt)."
Und hier haben wir schon das nicht so Gelungene and diesem Buch! Immer wieder wird auf eine spätere Erörterung verwiesen. Kann man das Ganze nicht thematisch so aufbauen, dass solche Vorgriffe und Auf-Später -Vertöstungen weitgehend vermieden werden können? Ich denke, dass dies andere Autoren bewiesen haben.
"Statische Methoden, so kann man grob formulieren, sind »gewöhnliche« Unterpro- gramme. Insofern fallen sie aus dem objektorientierten Konzept ein wenig heraus. Sie sollten auch nur in solchen Situationen genutzt werden, in denen die eigentlich »richtigen« objektorientierten Methoden nicht angewendet werden können. Eine zu häufige Benutzung solcher Methoden zeigt gewöhnlich, dass die Lösung nicht objektorientiert entworfen wurde."
Guter Hinweis und danke für die 'normal'-Sprache in Anführungszeichen. Hilft mir jedenfalls auf primitive Weise zu verstehen; auch wenn wir alle wissen, dass es 'das Normale' an sich eigentlich gar nicht gibt oder geben sollte in unserem aufgeklärten Denken...
"Gleichwohl erscheint es sinnvoll, solche Methoden bereits vor dem eigentlich objekt- orientierten Teil zu beschreiben.

Es wird gezeigt, wie Methoden aufgerufen werden können, die " ...
Junge, kündige nicht so viel an, fang lieber direkt mit dem Erklären an!

...
"Schließlich wird die Verwendung statischer Variablen definiert. Auch hier ist Vor- sicht angebracht: statische Variablen sollten möglichst wenig verwendet werden."
Weitere Ankündigungen, aber immer wieder vermischt mit schon eigentlichen Teil- Aussagen und hinweisen, die dann beim eigentlichen Teil gar nicht mehr weiter aufgegriffen werden.

S.88

...
"Die Klasse MainApp enthält zusätzlich zur statischen Main-Methode zwei weitere Methoden: die void-Methoden F und G. Beide sind - wie auch die Main-Methode - als static definiert (sie werden also nicht in Bezug aufObjekte aufgerufen - hierzu später mehr!). Im Gegensatz zu Main sind sie nicht public - sie sind daher außerhalb der Klasse Mainapp nicht sichtbar (und somit auch nicht aufrufbar)."
...

S.97 Statische Attribute
using System; 

class MainApp {
  static int a;
   ...
...
"Eine statische Variable ist annähernd dasselbe wie eine globale Variable in C. Sie existiert zur gesamten Laufzeit des Programms und ist prinzipiell aus allen Kontex- ten heraus ansprechbar."
Sehr hilfreich für die immer größer werdende Anzahl an Leuten, die erst gar nicht mit C anfangen, wenn sie programmieren lernen. Aber das Buch richtet sich erklärtermaßen nicht an blutige Anfänger, muss ich zur Entschuldigung der Autoren anführen.
"Sie unterscheidet sich nur dadurch von globalen C-Variablen, dass sie im Namens- raum einer Klasse eingebettet ist. Das bedeutet dreierlei: Erstens kann sie öffenlich oder nicht öffentlich sein (die a-Variable von C ist öffenlich, die namensgleiche Variable von MainApp ist nicht öffentlich); zweitens können Variablen verschiedener Klassen den gleichen Namen besitzen; und drittens muss beim Ansprechen einer sol- chen Variablen, die in einer anderern Klasse als der aktuellen definiert ist, der Name dieser Variablen mit dem Namen der Klasse präfixiert werden."
Präfixiert ? Pränatale Fixierung an die Mutter als Bezugsperson fördert später prämenstruelle posttraumatische Störungen des femininen Adoleszenz-Subjekts, oder so ...
"Man beachte, dass solche statischen Variablen nur dann verwendet werden sollten, wenn es nicht anders geht. Statische Variablen sind eigendich nicht objektorientiert wie auch statische Methoden eigentlich nicht objektorientiert sind."
Okay, ich verspreche Euch hiermit: Nur gaaaanz-ganz selten, wenn es wirklich nicht anders geht, also wenn ich sonst nicht ein noch aus weiß, werde ich diesen static-Dreck anfassen, heiliges Programierer-Ehrenwort!

S.123 Parameterlose void-Methoden

...

Bisheriger Stand des Beispiels mit Druck-Aktionen im Hauptmenü war dieser hier (stark abgekürzt durch den Kritiker):
  using System;
  class Konto {
    public int nr;
    public double bestand;
  }

  public static void Main() {
    Konto ko = new Konto();  
    ko.nr=4711; ko.bestand=3000;
    Console.WriteLine(ko.nr); 
    Console.WriteLine(ko.bestand);
  }
"Die Verantwortung für das Drucken ihrer Objekte übernimmt jetzt die Klasse Konto selbst.

Die bislang statische Methode der MainApp-Klasse wurde in die Klasse Konto verla- gert:"
  using System;

  class Konto {
    public int nr;
    public double bestand;

    public void DruckDich () {
       Console.WriteLine(this.nr);
       Console.WriteLine(this.Bestand)
    } 
  }

  class MainApp {  
   
    public static void Main() {
       
       Konto k1 = new Konto();  
       k1.nr=4711; k1.bestand=3000;
      
       Konto k2 = new Konto();  
       k2.nr=4712; k1.bestand=8000;

       k1.DruckDich();
       k2.DruckDich();
   }
 }
Bei der Verlagerung in die Klasse Konto wurden einige änderungen vorgenommen:
# Die Methode wurde umbenannt zu DruckDich.
# Die Methode ist nun nicht mehr static.
# Und die Methode hat (scheinbar) keinen Parameter mehr.

Tatsächlich hat auch diese Methode einen Parameter - nur wird dieser vom Com- piler automatisch generiert: Er ist vom Typ Konto (weil die Methode zur Klasse Konto gehört) und hat den Namen this. Der Parameter, der in der alten Lösung explizit definiert werden musste (und der dort als k bezeichnet worden war), wird bei nichtstatischen Methoden also automatisch vom Compiler generiert. Insofern wird dann auf die Attribute des zu druckenden Kontos auch nicht mehr über k, son- dern über this zugegrififen. Technisch ist alles beim Alten geblieben - nur die For- mulierung hat sich geändert.

Auch der Aufruf dieser Methode hat sich geändert. In der alten Lösung wurde die Referenz aufdas zu druckende Konto als Parameter an die statische DruckeKonto- Methode übergeben. Hier nun wird diese Referenz dem Namen der Methode voran- gestellt:"
  k1.DruckDich (); 
  k2.DruckDich (); 
Natürlich wird auch hier der Inhalt der Referenz wieder an die Methode übergeben - und zwar an den this-Parameter dieser Methode.

Der Name DruckDich ist vielleicht etwas merkwürdig (kein Mensch würde in einem richtigen Programm natürlich diesen Namen nutzen). Aber er ist einigermaßen sug- gestiv: Man möchte einem Konto »Bescheid sagen«: hallo du da, Konto: druck dich! Und genau dies ist im Sinne der Objektorientierung."
Okay, geht mir genau so, lieber merkwürdig, aber dafür merkfähig, also merkwürdig im eigentlichen Wortsinn.
"Noch einmal zurück zum this-Parameter, den automatisch alle nichtstatischen Methoden einer Klasse besitzen:

Innerhalb einer Methode einer Klasse existiert stets eine Referenz namens this.

Diese Referenz verweist innerhalb der Funktion auf dasjenige Objekt, für welches die Funktion aufgerufen wurde. "
Wirklich klare Erklärung - nicht mehr und nicht weniger, weiter so!
"Beim Aufruf: k1.DruckDich() verweist this auf dasjenige Objekt, auf welches k1 verweist; beim Aufruf k2.DruckDich() verweist this auf dasjenige Objekt, auf welches k2 verweist. Man kann auch sagen, dass beim Aufruf diejenige Referenz, über welche die Methode aufgerufen wird, an this über- geben wird. this ist also ein Parameter der Funktion (der formale Parameter), an welchen die Referenz, auf die die Methode aufgerufen wird, als aktueller Parameter übergeben wird."
Na, ist das nicht ein wenig holprig formuliert?

Man schmeckt förmlich die Mühe des Autors beim Formulieren heraus; als wenn er sich selbst nicht sicher wäre, ob das so eben Geschriebene zu verstehen ist. Ich hätte vielleicht so formuliert: 'Beim Aufruf: k1.DruckDich() verweist this - in der Methode DruckDich (!) - auf dasjenige Objekt, für das k1 steht '...
"Anders gesagt: über this kann innerhalb der Methode dasjenige Objekt angespro- werden, für welches die Methode aufgerufen wird. Bezeichnet man dieses Objekt als das »aktuelle Objekt«, so kann man verkürzt sagen: mit this ist immer das aktuelle Objekt der Aufrufs gemeint (genauer: this ist eine Referenz auf das aktuelle Objekt)."
Aah, dann hätte ich meine Ersatz-Formulierung ja sparen können! Hier steht alles noch viiiel treffender und mehrfach in anderen Worten gekleidet, bestens!
"Auf diese Weise ist die Methode allgemein: Sie kann den Zustand jedes beliebigen Objekts drucken. Genau das ist natürlich auch der Sinn der Sache."
  druckeKonto (kl); 
  druckeKonto (k2);


Naja, das hätte aber eine static-Methode mit dem K1 oder k2 als überzugebendem Parameter allerdings auch geleistet, oder?




D05 - Loop    ↑    Moses / Nowak :C# Progammieren unter .Net



S.76
"Die while-Schleife
  using System;

  class MainApp {
     public static void Main () { 
     Console.Write("Exponent: ");
     int exponent= Convert.ToInt32 (Console.ReadLine() );

     const int basis 0 2;
     int zaehler = 1;
     int ergebnis = basis;

     while (zaehler < exponent) { 
        ergebnis = ergebnis * basis;  
        zaehler = zaehler +1;
     }
  
    Console.WriteLine(ergebnis);
Das obige Programm demonstriert die Verwendung der while-Schleife. Es berechnet eine beliebige Potenz von 2. Der Exponent wird eingegeben. Die Variable basis wird als const definiert. D.h., diese Variable muss unmittelbar bei ihrer Definition initialisiert werden. Ihr Wert kann später nur noch gelesen, nicht aber mehr geändert werden.

Die while-Schleife umfasst zwei Anweisungen. Diese Anweisungen müssen mit ge- schweiften Klammern zu einem Block zusammengefasst werden. Sofern nur eine einzige Anweisung wiederholt werden muss, braucht diese Anweisung nicht ge- klammert zu werden. Der Block, der mittels der geschweiften Klammern gebildet wird, fungiert nach außen hin wiederum als eine einzige Anweisung.

Eine while-Schleife ist also wie folgt aufgebaut:
while (Ausdruck) 
  Anweisung;
"






D06 - Static    ↑    Andrew Troelsen : C# und die .Net-Plattform



S.115 Statische Methoden und Instanzmethoden
"Wie Sie gesehen haben, können Methoden als statisch deklariert werden. Aber was ist eine statische Methode überhaupt? Wenn eine Methode mit dem Schlüsselwort static markiert wird, kann sie direkt auf Klasseneben aufgerufen werden, ohne dass eine Objektinstanz erforderlich ist. Aus diesem Grund wird Main() als static deklariert, damit das Laufzeitsystem diese Funktion aufrufen kann, ohne eine neue Instanz der definierenden Klasse zuweisen zu müssen. Diese Funktion ist sehr nützlich, da Sie sonst ein Objekt erstellen müssten, um ein Objekt zu erstellen, das ein Objekt erstellt (...)."
Hurtig aber treffend vorgebracht!

Es folgt ein Beispiel
  public static string Complain()
  {
    string[] messages = new string[5]{"Do I have to?",
      "He started -it!", "I'm too tired...",
      "I hate school!", "You are sooo wrong."};
    return messages[CetRandomNumber(5)];
  }
"Der Aufruf einer statischen Methode ist einfach. Sie müssen lediglich den Member an den Namen der definierenden Klasse anhängen:"
  public static void Main(string[] args)  
  {
    for(int i =0; i < 40; i++) 
      Console.WriteLine(Teenager.Complain());
  }
Was heißt hier 'den Member' ? Hier ist wohl ein Element gemeint, das zu einr Klasse gehört, und in diesem Fall eben unsere static Methode sein soll!
"Bei nichtstatischen Methoden (Instanzmethoden) handelt es sich um Methoden, die auf Objektebene gültig sind. Wenn Complain () nicht als static markiert wäre, müssten Sie eine Instanz der Teenager-Klasse erstellen, bevor Sie sich das folgende Gemeckere anhören können:"
  Teenager joe = new Teenager();
  joe.Complain();
Das Beispiel ist ja eigentlich ganz gut gewählt. Lobenswert ist auch, dass der Autor überhaupt static und nicht-static Methode mit einem Beispiel in eben diesen zwei Varianten ablaufen lässt. Noch besser wäre es freilich, wenn die nicht-statische Methode nicht nur an das Objekt 'teenager Joe' gehängt wäre, sondern diese Methode eine Transformation bewirken würde, die bei Joe eben etwas anderes bewirkt als bei Jane - je nach dem, welche anderen Eigenschaften bei Joe und welche bei Jane zu finden sind... naja, vielleicht gehen meine Wünsche zu weit. Irgendwie verstehe ich hier noch nicht, was damit gewonnen ist. Methoden überhaupt andeers als static zu definieren.

Man könnte ja auch eine static Methode mit dem Subkjekt der Handlung als übergabeparameter definieren: complain('Joe'); complain('Jane'). Wäre aber vielleicht nicht so gut auf unsere natürlichen Sprachgewohnheiten ausgerichtet.

Definieren statischer Daten
"Zusätzlich zu statischen Methoden kann eine C#-Klasse auch statische Datenmember definieren. Denken Sie daran, dass eine Klasse normalerweise mehrere Zustandsdaten definiert. Dies bedeutet lediglich, dass jede Obiektinstanz eine interne Kopie der zu Grunde liegenden Werte verwaltet. Wenn Sie eine Klasse wie folgt definiert haben:"
  class Foo
  {
     public int intFoo;
   }
"können Sie daher eine beliebige Anzahl von Objekten des Typs Foo erstellen und das IntFoo-Feld auf einen eindeutigen Wert festlegen:"
  // jeder Foo-Verweis unterhält eine Kopie des IntFoo-Feldes.
  Foo f1 = new Foo();
  f1.intFoo = 100;

  Foo f2 = new Foo();
  f2.intFoo = 993;
"Statische Daten werden demgegenüber von allen Objektinstanzen gemeinsam genutzt. Anstatt in jedem Objekt eine Kopie eines bestimmten Feldes zu speichern, wird ein statischer Datenpunkt genau ein Mal zugewiesen."
...

Es folgt ein Beispiel einer Klasse mit dem sattsam bekannten Zähler für die instanziierten Objekte, wobei aber interessanterweise auf zwei verschiedenen Wegen auf den selben Zähler zugegegriffen wird: static und an ein Objekt gebunden; in dieser Deutlichkeit werden diese Unterschiede selten dargestellt:
"Beachten Sie, dass die Airplane-Klasse zwei Methoden definiert. Die statische GetNumber()-Methode gibt die aktuelle Anzahl der Airplane-Objekte zurück, die von der Anwendung zugewiesen wurden. GetNumberFromObject() gibt ebenfalls die statische Ganzzahl NumberInTheAir zurück. Da diese Methode aber nicht als statisch definiert wurde, muss der Objektbenutzer diese Methode aus einer Instanz von Airplane aufrufen."
(Es folgt der Aufruf dieser Methoden und deren Ergebnis als Bildschirmausgabe)
"Wie Sie sehen können, verwenden (sehen) alle Instanzen der Airplane-Klasse denselben Datenpunkt. Dies ist der Kempunkt statischer Daten: Alle Objekte verwenden einen bestimmten Wert auf Klassenebene (und nicht auf Objektebene) gemeinsam."




D06 - Loop    ↑    Andrew Troelsen : C# und die .Net-Plattform



S.107
"Die Schleifenkonstrukte while und do/while

Sie haben bereits gesehen, dass die for-Anweisung normalerweise verwendet wird, wenn bereits Kenntnisse über die Anzahl der Iterationen vorliegen, die durchgeführt werden sollen (z. B., Schleife durchlaufen, bis j > 20). Die while-Anweisung ist demgegenüber von Nutzen, wenn Sie nicht wissen, wie lange es dauert, bis eine Abschlussbedingung erfüllt ist.

Zur Veranschaulichung der while-Schleife werfen Sie nachstehend einen kurzen Blick auf die Dateibearbeitung in C# (die ausführlich in Kapitel 11 dargestellt wird). Die StreamReader-Klasse, die im System.IO-Namespace definiert ist, enthält die zum Lesen einer bestimmten Datei notwendigen Details. Sie erhalten eine Instanz des StreamReader-Typs als Rückgabewert der statischen File.OpenText()-Methode. Nachdem Sie die Datei config.win geöffnet haben, können Sie mit StreamReader.ReadLine() alle Zeilen in der Datei durchlaufen:
  try  // Für den Fall, dass die richtige Datei nicht gefunden werden kann.
  {
     // Datei mit dem Namen 'config.win' öffnen.
    StreamReader strReader = File.OpenText("C:\\config.win");
    string strLine;
    while (null != (strLine = strReader.ReadLine()))
    {
      Console.WriteLine(strLine);
    }
   // Datei schließen.
   strReader.Close();
   catch(FileNotFoundException e)  
   // Ausnahmen werden wir ausführlicher in Kapitel 3 kennen lernen.
   {
      Console.WriteLine(e.Message);
   }
Eng verwandt mit der while-Schleife ist die do/while-Anweisung. Wie eine einfache while-Schleife wird do/while verwendet, wenn Sie eine Aktion mit einer unbekannten Häufigkeit durchführen müssen. Der Unterschied besteht darin, dass do/while-Schleifen den entsprechenden Codeblock garantiert mindestens ein Mal ausführen. Im Gegensatz dazu ist es möglich, dass eine einfache while-Schleife niemals ausgeführt wird, wenn die Abschlussbedingung von Beginn an falsch ist. Die Ausgabe der Iterationslogik ist in Abbildung 2.14 dargestellt.
  // Die do/while-Anweisung
  string ans;
  do
  {
     Console.Write("Are you done? [yes] [no] : ");
     ans = Console.ReadLine();
  }
  while (ans != "yes");
"






D07 - Static    ↑    Golo Haas : Guide To C Sharp

"Die Angabe static kann sowohl bei Datenelementen als auch bei Methoden gemacht werden und bewirkt, dass immer genau eine Instanz dieses Datenelementes oder dieser Methode existiert, unabhängig davon, wie viele Objekte existieren (und, ob überhaupt eines existiert)."
Kurz und knapp, okay.; besonders der letzte zusatz gefällt mir: "..ob überhaupt eines existiert".
"Statische Datenelemente können beispielsweise dazu verwendet werden, die Anzahl der von einer Klasse erzeugten Objekte zu zählen, indem die Variable beim Anlegen eines neuen Objektes durch den Konstruktor automatisch um eins erhöht wird. Dadurch, dass das Datenelement in jedem Fall nur genau einmal existiert, ist sichergestellt, dass alle Objekte auf das selbe Datenelement zugreifen. "
Wieso 'in jedem Fall' ? Also etwa genau einmal pro Fall, oder was? Oder ist 'auf jeden Fall' gemeint? Und wieso sollten die Objekte gemeinsam auf eine solches Klassen-Element zugreifen? Um sich selbst zu zählen? Es wurde doch eben noch formuliert, dass statische Datenelemente unabhängig von etwaigen Instanzen existieren können.

Es ist hier wohl eher gemeint, dass ein statisches Datenelement nur ein einziges Mal in der ganzen Klasse existiert, um dort Dinge zu regeln, die nicht ein einzelnes Objekt dieser Klasse betreffen, sondern Dinge, die die ganze Klasse zusammen genommen betreffen.
"Werden in einem Programm nun beispielsweise vier Objekte der Klasse CZaehler angelegt, so gibt jedes Objekt bei seiner Erstellung auf dem Bildschirm aus, das wievielte dieser Klasse es ist. "
  ErstesObjekt = new CZaehler();
  ZweitesObjekt = new CZaehler();
  DrittesObjekt = new CZaehler();
  ViertesObjekt = new CZaehler();
Wieso wird hier die Klasse 'CZaehler' genannt? Das ist natürlich nicht falsch, aber ist das wirklich hilfreich, um ein anschauliches Beispiel vor Augen zu stellen? Die Klasse soll ja bestimmt für irgendetwas anderes stehen, als dass irgendwelche Objekte erstellt werden, deren höchste Aufgabe darin besteht, gezählt zu werden, nicht wahr?
"Statische Datenelemente kommen in der Praxis nicht sehr oft vor, aber falls einmal eine entsprechende Funktionalität benötigt wird - nämlich, dass alle Objekte gemeinsam auf einen gemeinsamen Wert zugreifen - , so bieten sie eine sehr elegante Lösung."
Ne-nee, das mit dem 'gemeinsam zugreifen' ist so eine Sache: Das kann zwar sein (zB summiere meinen Betrag mit dem der anderen auf und lege mich nur an, wenn es diesen Betrag noch nicht gibt) , es kann aber auch sein, dass es eine übergeordnete Verwaltung gibt, die auf diese Objekte zugreifen soll (zählen, den höchsten ermitteln, ...) .

Und was soll daran 'sehr elegant' sein? Es ist eine schlichte Notwendigkeit, dass eine Computersprache auch so etwas ermöglicht. Im Gegenteil, zu häufiger Gebrauch von 'static' deutet darauf hin, dass der Programmierer die Möglichkeiten der OOP nicht nutzt und seine althergebrachten prozeduralen Gewohnheiten nicht ablegen kann.
"Statische Methoden hingegen kommen in der Praxis etwas öfter vor. Ihr Sinn besteht darin, eine Methode auch aufrufen zu können, ohne vorher ein Objekt der entsprechenden Klasse anlegen zu müssen. Deswegen ist beispielsweise die Main-Methode statisch, da von der Klasse, in der Sie enthalten ist, nie ein Objekt angelegt wird. Damit die Funktion trotzdem existiert und aufrufbar ist, muss sie als statisch definiert werden."
Okay
"Wie bei den Objekten haben Sie auch schon mit weiteren statischen Methoden gearbeitet, ohne es zu wissen. Beispielsweise ist der Befehl für die Bildschirmausgabe, WriteLine, eine statische Methode der Klasse Console, wie oben bereits erwähnt wurde: Sie legen nämlich nie ein Objekt der Klasse Console an, sondern verwenden die Klasse immer so, als sei sie bereits ein Objekt. Auch diese Funktionalität wird durch das Schlüsselwort static ermöglicht.
Gutes Beispiel, okay.



D07 - Loop    ↑    Golo Haas : Guide To C Sharp

Schleifen

"In diesem Kapitel werden Sie lernen, was Schleifen sind und welche Arten von ihnen es in C# gibt.

Einleitung

Nachdem Sie im letzten Kapitel bereits gelernt haben, wie Sie den linearen Ablauf von Programmen mit Entscheidungen durchbrechen können, lernen Sie nun noch eine weitere Technik dazu kennen."
Entschuldigung, dass ich mich hier npch einmal zu Wort melde, aber ich kann diesen Ankündigungsstil nicht unkommentiert stehen lassen. Denn dieser zieht sich durch das ganze Buch. Zwei Sätzchen zur Einstimmung am Anfang jedes Kapitels, damit der Leser nicht gleich erschrickt vor der ungwohnten Materie und dann noch 2 Sätzhcen beim Abspann, um noch einmal zu rekapitulieren, wa man verdaut hat... Ich halte nichts von dieser Marotte, auch wenn sie lieb gemeint ist!
"Schleifen dienen dazu, Anweisungen wiederholt auszuführen, wobei entweder eine bestimmte Anzahl vorgegeben wird oder der Ablauf dynamisch gesteuert werden kann.

...

Die while-Schleife

Der Nachteil der for-Schleife ist, dass von vornherein feststehen muss, wie oft sie durchlaufen werden soll. Eine Schleife, die so lange läuft, bis (irgendwann) ein bestimmtes Ereignis eintritt, ist so nicht zu realisieren. Für solche Aufgaben gibt es in C# die while-Schleife.

Im Kopf der while-Schleife wird ein Ausdruck übergeben, und so lange dieser wahr ist, wird die Schleife ausgeführt. Sie müssen aber darauf achten, dass die Bedingung auf jeden Fall irgendwann wahr werden kann, sonst befindet sich das Programm in einer Endlosschleife.
  using System;
 
  public class Kreis
  {
    public static void Main()
    {
      const double Pi = Math.PI;
      double Flaeche;
      int Radius = 1;
      bool NochmalBerechnen = true;
 
      while(NochmalBerechnen)
      {
        Flaeche = 2 * Pi * Radius * Radius;
        Console.Write("Der Kreis mit dem Radius {0} hat ", Radius);
        Console.WriteLine("die Fläche {0}!", Flaeche);
        Radius++;
        Console.Write("Möchten Sie die Fläche des ");
        Console.Write("nächsten Kreises berechnen (j / n)? ");
        if(Console.ReadLine() != "j")
        {
          NochmalBerechnen = false;
        }
      }
    }
  }
Dieses Programm berechnet nacheinander die Flächen von Kreisen mit dem Radius 1, 2, 3, ... so lange, bis der Anwender eingibt, dass er keine weitere Fläche mehr berechnen möchte, also die Variable NochmalBerechnen auf false gesetzt wird. Beachten Sie bitte, dass hinter der while-Anweisung kein Semikolon kommt. Die geschweiften Klammern sind optional, solange der Schleifenkörper aus nur einer Zeile besteht.

Die Syntax der while-Schleife lautet also :
  while(Bedingung)
  {
    Anweisungsblock;
  }
In einem Punkt verhält sich die while- genauso wie die for-Schleife, sie sind nämlich beide abweisend. Das heißt, dass die Schleife unter Umständen nicht ein einziges Mal durchlaufen wird. Das kann passieren, wenn die Bedingung von vornherein falsch ist.
  bool Bedingung = false;
  while(Bedingung)
  {
    ...
  }
wird beispielsweise nie ausgeführt, da die Variable Bedingung von Anfang an den Wert false enthält. Genauso wenig wird die for-Schleife
  for(i = 1; i > 100; i++)
  {
    ...
  }
ausgeführt, da i am Anfang den Wert 1 hat, die Schleife aber ausgeführt werden soll, solange i größer als 100 ist.

Vielleicht ist Ihnen in dem Programm außerdem die Zeile const double Pi = Math.PI; aufgefallen. Hier wird eine Variable Pi vom Typ double definiert, aber zusätzlich mit dem Schlüsselwort const versehen. Dadurch kann der Wert von Pi im Lauf des Programms nicht mehr verändert werden, sondern Pi stellt eine Konstante dar.

Der Wert einer Konstanten muss ihr gleich bei der Deklaration übergeben werden, da Sie später nicht mehr schreibend auf die Konstante zugreifen können. Als Wert wird in diesem Fall Math.PI übergeben.

PI ist eine vom .net Framework vorgegebene Konstante, die in Math enthalten ist (so wie WriteLine in Console enthalten ist), Math wiederum ist System untergeordnet. Math enthält mathematische Funktionen und wichtige mathematische Konstanten wie Pi oder die Zahl e. Natürlich hätten Sie in dem Programm auch direkt mit System.Math.PI arbeiten können, statt diesen Wert der Konstante Pi zuzuweisen.

Die do-Schleife

Es gibt noch eine weitere Schleife in C#, die der while-Schleife sehr ähnlich ist, nämlich die do-Schleife. Sie unterscheidet sich von der while-Schleife nur in dem Punkt, dass sie nicht abweisend ist und somit auf jeden Fall mindestens ein Schleifendurchlauf stattfindet.
  using System;
 
  public class Kreis
  {
    public static void Main()
    {
      const double Pi = Math.PI;
      double Flaeche;
      int Radius = 1;
      bool NochmalBerechnen = true;
 
      do
      {
        Flaeche = 2 * Pi * Radius * Radius;
        Console.Write("Der Kreis mit dem Radius {0} hat ", Radius);
        Console.WriteLine("die Fläche {0}!", Flaeche);
        Radius++;
        Console.Write("Möchten Sie die Fläche des ");
        Console.Write("nächsten Kreises berechnen (j / n)? ");
        if(Console.ReadLine() != "j")
        {
          NochmalBerechnen = false;
        }
      }
      while(NochmalBerechnen);
    }
  }
Dieses Programm hat genau die selbe Wirkung wie das Beispiel der while-Schleife, aber es ist mit einer do-Schleife programmiert. Die Syntax der do-Schleife lautet also
  do
  {
    Anweisungsblock;
  }
  while(Bedingung);
Beachten Sie bitte, dass hinter dem do kein Semikolon steht, hinter dem while aber sehr wohl eines! Stünde hier keins, könnte der Compiler das Ende der do-Schleife und den Anfang einer while-Schleife nicht unterscheiden.

Auch wenn es nicht noch einmal ausdrücklich erwähnt wurde, funktionieren die break- und die continue-Anweisung in der while- und der do-Schleife auf die selbe Art und Weise wie bei der for-Schleife."






D08 - Static    ↑    Erler / Ricken : C# - Das Einsteigerseminar

S.112 Klassenattribute und -operationen
"Eine Klasse beschreibt ein Muster für die Erstellung von Objekten. Sie definiert dazu Attribute und Operationen, die den Objekten bei der Erzeugung mitgegeben werden. Damit besitzt jedes Objekt eine eigene Kopie dieser Attribute und Operationen."
Leider zweideutig: 'Damit besitzt jedes Objekt eine eigene Kopie dieser Attribute und Operationen' - also eine exakte Kopie mit dem selben Inhalt? Nein! Nur ein gleicher Behälter wird angelegt. 'Kopie' trifft die Sache nicht.
"Es gibt jedoch auch spezielle Attribute und Operationen, die in einer Klasse nur ein einziges Mal existieren und für alle Objekte identisch sind. Diese so genannten Klassenattribute und Klassenoperationen werden den Objekten bei der Erzeugung nicht mitgegeben. Sie werden gekennzeichnet durch das Schlüsselwort static."
'und für alle Objekte identisch sind' - wieso überhaupt für Objekte? Es funktioniert ja auch, ohne dass Objekte erstellt worden sein müssen.
"Eine Klassenoperation ist Ihnen bereits bekannt: die Main()-0peration. public static void Main(string[] args){. . .}"
"Das Schlüsselwort static schließlich markiert Main() als Klas- senoperation. Damit ist diese Operation zusätzlich über die Klas- se Start - und nicht nur über ihre Objekte - verfügbar. Das be- deutet, dass kein Objekt erzeugt werden muss, um die Main()- Operation aufzurufen."
'Wieso zusätzlich? Ich dachte, dass gerade Main nur diesen einen Zweck erfüllt. Und auch für alle anderen gilt doch: Nur über die Klasse direkt ansprechbar, unabhängig von Objekten! Also alles andere als zusätzlich. Oder habe ich da irgendetwas noch nicht begriffen? ...
"Es muss also eine Möglichkeit geben, Operationen auszuführen, die nicht an Objekte gebunden sind. Hier bieten sich die Klassen als Trä- ger solcher Operationen an, da sie ja als Muster bereits existieren. Ge- nau aus diesem Grund ist die Main()-0peration eine Klassenoperation. Zu Beginn eines Programms existieren noch keine Objekte. Es gibt aber sehr wohl bereits Klassen, von denen genau eine immer eine Main()-Operation enthält, um den Startpunkt des Programms festzule- gen und die ersten Anweisungen zu definieren."
Naja, hier wird es erst einmal klarer: 'nicht an Objekte gebunden'. Aber schon dozieren die Herren Doctores wieder daher: 'Hier bieten sich die Klassen als Träger solcher Operationen an, da sie ja als Muster bereits existieren...' Oh Mann! Wieso 'anbieten' ? Diskutieren wir jetzt locker mit, wie man eine Programmiersprache baut? Oder bietet sich realiter noch etwas anderes an?
"Darüber hinaus können Sie auch eigene Klassenoperationen und -attribute implementieren. Häufig werden diese dazu verwendet, Auf- gaben zu übernehmen, die alle Objekte einer Klasse betreffen."
(Nun folgt ein Beispiel von Verkehrsampeln, das in seiner Originalität und in seiner Anschaulichkeit für mich noch das beste an diesem Buch ist).

...

S.116 Das Schlüsselwort this
"Das Beispiel der Ampel hat verdeutlicht, dass Sie gleichartige Objekte in C# nur ein einziges Mal in einer Klasse beschreiben müssen, um mit Hilfe dieses Musters anschließend beliebig viele Objekte erzeugen zu können. Die Klassendefinition ist daher möglichst allgemein gehal- ten. Sie soll für jede ihrer Exemplare Gültigkeit besitzen. Dadurch kann es im Programmverlauf zu Mehrdeutigkeiten kommen, bei denen nicht klar ist, worauf sich eine Anweisung bezieht. Folgendes Beispiel soll die Problematik verdeutlichen.

Die Anweisung meineAmpel.SetRot(false) ist eindeutig. Sie bezieht sich auf die Operation SetRot(), die zu dem Objekt meineAmpel gehört. Hat die Klasse Ampel beispielsweise die Struktur des folgenden Programmfragments, so bereitet auch die Aus- führung der Operation keine Schwierigkeiten. Die Anweisungen sind eindeutig:"
  class Ampel
  {
     bool rot;
     public void SetRot(bool r)
     {
        rot = r;
     }
  }
"Der Aufruf meineAmpel .SetRot(false) setzt das Attribut rot auf den Wert des Parameters r. Diesem wiederum wird zuvor der Wert des Arguments des Operationsaufrufs (false) zugewiesen. Bisher wurden die Variablen in den Parameterlisten der Operationen stets mit wenig aussagekräftigen Namen bezeichnet. Das trägt nicht gerade zum Ver- ständnis des Programmcodes bei. Es gehört zu einem guten Program- mierstil/ Variablen sinnvolle verständnisfördernde Namen zu geben. Die bisher verwendeten Parameter r, ge und gr sollten daher besser als rot, gelb und gruen bezeichnet werden. Die Eindeutigkeit der Zuwei- sung geht jedoch verloren, wenn Sie die Operation aus dem obigen Programmfragment wie folgt ändern:"
  bool rot;
  public void SetRot(bool rot);
    {
       rot = rot; // nicht eindeutig!
    }
"Die Mehrdeutigkeit tritt hier in Zeile 6 auf. rot bezeichnet sowohl ein Attribut von Objekten der Klasse Ampel, als auch einen Parameter. Nach dem Aufruf von meineAmpel .SetRot(false) tritt bei der Anweisung rot = rot ein Konflikt auf. Um dieser Problematik zu begegnen, gibt es das Schlüsselwort this. Es bezieht sich in einer Klassendefinition immer auf das aktuelle Objekt, für das eine Operation ausgeführt wird. In dem obigen Programmfragment lautet die Anweisung in Zeile 6 dann:"
  this.rot = rot;
  //eindeutig!
"In dieser Form ist die Anweisung eindeutig: "Weise den Wert des Parameters rot dem Attribut rot des aktuellen Objekts (hier: meineAmpel) zu." Einige wichtige Grundkonzepte der objektorientierten Programmierung haben Sie damit schon erfahren."
Oh Gott, irgendetwas verstehe ich hier nicht!

Aus welchem Grund sollte ich gut auf die Idee kommen, einen übergabeparameter 'rot' zu nennen für eine Methode SetRot, die nichts anderes macht als diesen Parameter auf true, also gleichfalls auf 'rot' zu stellen und darin noch eine bolsche Variable zu deklarieren, die ich dann ebenfalls 'rot' nenne ??? Hä? Ein Mann sieht rot!

Den Sinn von 'this' kann man meiner Meinung nach viiiel besser erklären! Ich würde so ein babylonisches Sprachgewirr mit mir selber jedenfalls nicht veranstalten! Wenn ich eine Variable, die nichts weiter als den Wert 'rot' = ja oder = nein annehmen kann, ebenfalls einfach nur 'rot' nenne, statt z.B. 'istRot' oder ähnlich, dann brauche ich natürlich die 'this'-Hilfe aus diesem Schlamassel. Aber irgendwie verbietet es mir mein Instinkt, überall die selben Literale einzusetzen.

Diese Art von Beispielen sind es, die mir als Beginner OOP so ungeheuer umständlich und formalistisch und verwirrend und ideenarm vorkommen liess - was sich allerdings inzwischen dank guter Erklärungsanätze anderer Autoren grundlegend geändert hat...





D08 - Loop    ↑    Erler / Ricken : C# - Das Einsteigerseminar



S.145

"Die do-while-Schleife - erst arbeiten, dann prüfen

Wenn wir vor dem Füllen in der Schleife die Karaffe entleeren, können wir sicher sein, dass mindestens eine Fülloperation erforderlich ist, um die Karaffe bis zum Fassungsvermögen zu füllen.
kleine Karaffe leeren
      1 I in kleine Karaffe einfüllen
      Ausgabe Füllmenge
Solange. bis die kleine Karaffe voll ist
Das Struktogramm zeigt diese fußgesteuerte Schleife. Die erste Prü- fung, ob die beiden Anweisungen im Schleifenkörper, Füllen und Aus- gabe, ausgeführt werden, erfolgt erst nach dem ersten Schleifenlauf. Somit ist gewährleistet, dass die Schleife mindestens einmal durchlau- fen wird. Anders als bei der kopfgesteuerten Schleife, die durchlaufen wird, wenn die Schleifenbedingung wahr ist (so lange, wie ...) wird die fußgesteuerte Schleife durchlaufen, so lange die Schleifenbedingung nicht wahr ist (so lange, bis...).

Setzen Sie auch diesen Ablauf, der im Struktogramm festgelegt ist, in der Main () -Operation der Startklasse in ein C#-Programm um."
// Listing 4.9
class Start {

static void Main(string[] args) {
Karaffe kleineKaraffe = new Karaffe(5), großeKaraffe = new Karaffe(7);
kleineKaraffe.Leeren();

do {
   kleineKaraffe.Füllen(1);
   kleineKaraffe.Ausgeben();
}

while(kleineKaraffe.IsVoll() );
Nachdem die Anweisung in Zeile 7 die kleine Karaffe sicherheitshalber entleert, füllt die do-while-Schleife (Zeile 8-12) das Gefäß wieder nach und nach bis zum Fassungsvermögen. Eingeleitet durch das Schlüssel- wort do folgt die Blockanweisung des Schleifenkörpers, der die beiden Anweisungen zum Füllen und zur Ausgabe enthäIt. Die Schleifenbe- dingung in Zeile 12 wird exakt so festgelegt wie bei der while-Schleife. Das erstaunt ein wenig, wo doch das Struktogramm die Bedingung so formuliert, dass em Ausdruck, der true liefert, zum Verlassen der Schleife führt, C# jedoch bei true die Anweisungen des Schleifenkör- pers (noch einmal) ausführt. Damit befindet sich C# jedoch in guter Gesellschaft mit anderen Programmiersprachen.

Formal ist die do-while-Schleife der while-Schleife sehr ähnlich. Dabei kennzeichnet do lediglich die Schleife, ohne dass eine Prüfung der Schleifenbedingung erfolgt.

do Anweisung while (Ausdruck);

Neben den grundlegenden Wiederholungsanweisungen bietet C# noch zwei weitere kopfgesteuerte Schleifen an. Die beliebte for-Schleife wird hauptsächlich als Zählschleife eingesetzt. Darüber hinaus existiert die foreach-Schleife, die festgelegte Anweisungen für jedes Element einer Sammlung ausführt."






D09 - Static    ↑    Eric Gunnerson : C#

9.6 Statische Felder
"Es ist manchmal sinnvoll, Mitglieder eines Objekts zu definieren, die nicht mit einer spezifischen Klasseninstanz, jedoch mit der Klasse als Ganzes verknüpft sind. Solche Mitglieder werden als statische (static) Mitglieder bezeichnet."
'Mitglieder eine Objektes?' Gehen da die Begriffe nicht ein wenig durcheinander? Solche Elemente gehören meiner Auffasung nach nicht zu Objekten, also zu Instanzen einer Klasse, sondern zu der Klasse direkt. Kann sein, dass der Autor mit 'Objekten' KLasse meint, dann würde ich es noch verstehen. Aber ich denke eher, dass er tatäschlich mit 'Objekten' Objekte als Klasseninstanzen meint, so unter dem Motto: was zu einer Klasse gehört, ist zunächst einmal ein Objekt. Und es gibt da noch etwas in einer Klasse, das ich folglich einfach erst einmal ebenfalls als einem Objekt zugehörig ansehe, aber dieses andere ist dann doch eher mit der Klasse als Ganzes und nicht einer Klasseninstanz (=Obkekt) verbunden.... Naja, entweder ich hab unklare Gedanken oder meine Gedanken werden bei solchen Definitionen unklar...
"Ein statisches Feld ist die einfachste Form eines statischen Mitglieds. Zur Deklaration eines statischen Feldes platzieren Sie einfach den Modifikator static vor der Variablendeklaration. Der folgende Code könnte beispielsweise dazu verwendet werden, die Anzahl der erstellten Klasseninstanzen zu verfolgen...."
Okay, das typische Beispiel; aber wieso 'einfachste Form' ? Kommen denn mit static Methoden noch die intellektuellen Herausforderungen, auf die man erst einmal langsam vorbereitet werden muss? Ich denke doch, dass nicht.
"Die Erstellungsroutine für das Objekt erhöht den Instanzenzähler, und der Instanzenzähler kann referenziert werden, um die Anzahl der bisher erstellten Objektinstanzen zu ermitteln. Auf ein statisches Feld wird nicht über die Instanz der Klasse, sondern über den Namen der Klasse zugegriffen; dies gilt für alle statischen Mitglieder."
'kann referenziert werden' - Mann, irgendwie klingt das recht hochgestochen; 'kann dann abgefragt oder angezeigt werden' oder so, würde doch auch schon genügen.

Und 'über die Instanz' - wieso über 'die' ? Gibt es denn nur eine? Oder soll jetzt von einer bestimmten die Rede sien, mit der schon vorher irgend etwas war, was sich übersehen habe? Pars pro toto? Ist zwar erlaubt, aber in diesem Fall verwirrend. Viel eindeutiger wäre: 'über eine Instanz'.

9.7 Statische Mitgliedsfunktionen ('...' = von mir gekürzt)
"Im vorangegangenen Beispiel wird ein internes Feld offen gelegt - eine nicht empfohlene Vorgehensweise. Das Codebeispiel kann so geändert werden, dass statt eines statischen Feldes eine statische Mitgliedsfunktion verwendet wird" ....
  ...
  public static int GetInstanceCount()
  {    
    return(instanceCount);   
  }
  static int instanceCount = 0;
  ...
  public static void Main()
  ...
  Console.WriteLine(MyClass.GetInstanceCount());
  ...
"Mit diesem Code wird das gewünschte Ziel erreicht, und gleichzeitig wird das Feld den Benutzern der Klasse gegenüber nicht offen gelegt, d. h., die Flexibilität hinsichtlich zukünftiger Codeänderungen wird erhöht. Da es sich um eine statische Mitgliedsfunktion handelt, wird sie über den Klassennamen und nicht über den Namen einer Klasseninstanz aufgerufen.

Im wirklichen Leben würde in diesem Fall wohl eher eine statische Eigenschaft verwendet. Diese werden in Kapitel 18, Eigenschaften, besprochen."
Na, ist das nicht ein bisschen kurz ausgefallen? Eigentlich müssten doch alle Methoden erst einmal static sein, im Sinne von nicht für jede Instanz kopiert werden, oder? Es gibt aber dennoch Methoden, die zur Laufzeit dem Objekt (=der bestimmten Klaseninstanz) zugeordnet sind, für die gerade diese Methode aufgerufen wird (also die 'normalen' Objekt-Methoden), und dann gibt es eben Methoden, die auf kein bestimmtes Objekt zeigen, sondern einfach nur der Klasse als Ganzes (oder als übergeordnetes oder als unabhängig von Objekten bestehendes) zugeordnet sind...

9.8 Statische Erstellungsroutinen
"Ebenso wie es statische Mitglieder gibt, gibt es auch statische Erstellungsroutinen. Eine statische Erstellungsroutine wird vor der Erstellung der ersten Objektinstanz aufgerufen und ist bei der Ausführung von einmalig anfallenden Setupaufgaben nützlich.

Eine statische Erstellungsroutine wird durch einfaches Hinzufügen von static vor der Erstellungsroutinendefinition deklariert. Eine statische Erstellungsroutine kann keine Parameter tragen."
class MyClass
{
    static MyClass()
    {
    }
}
"Es gibt zur Zerstörungsroutine keine analoge statische Zerstörungsroutine."
Okay, nicht jeder Autor weist darauf hin. Der Zweck leuchtet mir bei dieser Formulierung ebenfalls ein.

...

9.11 Private Erstellungsroutinen

Auch dieses hier ist keinesfalls überall aufzufinden, nützlich und halbwegs klar formuliert:
"Da es in C# keine globalen Variablen oder Konstanten gibt, müssen alle Deklarationen innerhalb einer Klasse vorgenommen werden. Manchmal entstehen so Klassen, die vollständig aus statischen Mitgliedern bestehen. In diesem Fall besteht keine Veranlassung dazu, jemals ein Objekt der Klasse zu instanziieren. " (diese klare Sprache hätte ich mir von Anfang an gewünscht!) "Um eine Instanziierung zu verhindern, wird der Klasse eine private-Erstellungsroutine hinzugefügt."
...

(es folgte ein knappes Beispiel hierzu)

...
"Obwohl durch das Hinzufügen von private vor der Erstellungsroutinendefinition der tatsächliche Zugriff auf die Erstellungsroutine nicht geändert wird, wird durch die explizite Kennzeichnung deutlich, dass die Klasse über eine private Erstellungsroutine verfügen soll."
'der tatächliche Zugriff nicht geändert' - hä? Meint er etwa: Den Ausdruck 'private' müssen Sie nicht ausdrücklich hinzufügen, da alles, was nicht anders definiert wird, grundsätzlich 'pivate' ist, aber es macht die Sache für den Leser des SourceCode noch deutlicher...?



D09 - Loop    ↑    Eric Gunnerson : C#

13.2.1 While
"Die while-Schleife funktioniert wie erwartet: Solange die Bedingung zutrifft, wird die Schleife ausgeführt. Wie die if-Anweisung, erfordert while eine boolesche Bedingung:
  using System;
  class Test
  {
    public static void Main()
    {
      int n = 0;
      while (n < 10)
      {
        Console.WriteLine("Number is {0}", n);
        n++;
      }
    }
  }
Die break-Anweisung kann dazu verwendet werden, die while-Schleife zu verlassen. Die state-Anweisung kann eingesetzt werden, um die schließende Klammer des while-Blocks für die Iteration zu überspringen und mit dem nächsten Durchlauf fortzufahren.
  using System;
  class Test
  {
    public static void Main()
    {
      int n = 0;
      while (n < 10)
      {
        if (n == 3)
        {
          n++;
          continue;
        }
        if (n == 8)
          break;
        Console.WriteLine("Number is {0}", n);
        n++;
      }
    }
  }
Dieser Code erzeugt die folgende Ausgabe:

0 1 2 4 5 6 7

13.2.2 Do

Eine do-Schleife funktioniert wie eine while-Schleife, abgesehen davon, dass die Bedingung am Ende der Schleife und nicht zu deren Beginn ausgewertet wird:
  using System;
  class Test
  {
    public static void Main()
    {
      int n = 0;
      do
      {
        Console.WriteLine("Number is {0}", n);
        n++;
      } while (n < 10);
    }
  }
Wie bei der while-Schleife, können die Anweisungen break und continue zur Steuerung des Schleifenablaufs eingesetzt werden."







D10 - Static    ↑    Helma Spona : C# - Der leichte Einstieg

S. 182 Statische Elemente der Klasse
"Bei einigen der bisher vervendeten Klassen des .NET Frameworks werden keine Instanzen der Klasse gebildet und dennoch die Metho- den und Eigenschaften genutzt, so beispielsweise bei den Klassen Sys- tem.String und System.DateTime. Das funktioniert, weil es sich um statische Klassen bzw. statische Elemente der Klasse handelt."
Hey, das ist ein bisschen schnell darein geholpert! 'und dennoch die Metho- den und Eigenschaften genutzt' ? - Ja welche denn? Wachsen diese Methoden einfach so aus dem .NET Framework oder wie? Und welche Rolle spielt jetzt der interessierte Leser dabei? Soll er das einfach als Eigenart dieses Frameworks hinnehmen, oder soll er diese Eigenart nicht besser als Möglichkeit begreifen, um selber ganz bestimmte Dinge mit static zu regeln ?
"Auch für Ihre eigene Klasse können Sie so etwas realisieren, indem Sie Elemente der Klasse mit dem Schlüsselwort static definieren. Wenn Sie nur die Eigenschaft Pi lesen möchten, lohnt es in der Regel kaum, dazu eine Klasseninstanz zu erzeugen. Wenn Sie die Eigenschaft auch so verfügbar machen möchten, fügen Sie nach dem Schlüsselwort public das Schlüsselwort static ein."
...

(es folgt ein kurzes Beispiel)

...

'auch so' ist übrigen doppeldeutig: es kann bedeutet: auf die gleiche Art und Weise; hier ist aber wahrscheinlich gemeint: auch ohne so etwas (Instanzbildung) ...

Tja, und das war es dann auch schon zu diesem Thema, wenn ich in dem schmalen Band nicht noch etwas übersehen haben sollte.
"Die Klasse verwenden

Wenn Sie die Klasse verwenden wollen, funktioniert das wie bei den Klassen des .NET Frameworks. Sie erzeugen eine Instanz der Klasse und können dann die definierten Elemente auf das Objekt anwenden. Die statische Eigenschaft müssen Sie dagegen direkt über den Namen der Klasse aufrufen."
  clsMath objMath=new clsMath(7);
  MessageBox.Show("Exponent: " + objMath.Exp.ToString());
  MessageBox.Show("'PI: " + clsMath.PI.ToString());
  MessageBox.Show("Summe: " + objMath.Summe(1,3,6).ToString());
Ich nix verstehen!!! Eine Instanz? Und dann die Elemente auf das Objekt anwenden? Bitte nicht so! Hier kann man doch nur erahnen, was gemeint ist, wenn man mindestens 3 andere Bücher über diese Thema gelesen hat, aber dann braucht man eben diesen kanppen Abriss gerade nicht mehr...

(S.123 This)

...
"Im Anschluss können Sie dann die Felder des Arrays füllen, indem Sie ihnen die Werte der Eingabefelder zuweisen. Sie werden von der Text- Eigenschaft des entsprechenden Feldes zurückgegeben. Der Ausdruck this.textBox1.Text gibt somit den Text des Textfeldes textBox1 zurück.

Das »Objekt« this

Mit dem Schlüsselwort this können Sie auf eine Instanz der Klasse zugreifen, in der Sie dieses Schlüsselwort verwenden. Innerhalb einer Klasse, dievon System.Windows.Forms.Form abgeleitet wurde, können Sie damit also auf das Formular und seine Steuerelemente zugreifen."
Viiiiel zu knapp für mich, Helma!



D10 - Loop    ↑    Helma Spona : C# - Der leichte Einstieg

"Schleifen

Schleifen dienen dazu, mehrere Anweisungen oder auch Methodenauf- rufe mehrfach nacheinander auszuführen. Wie jede andere Program- miersprache bietet auch C# mehrere Schleifenarten. Im Prinzip kann man mit jeder Schleife jedes Problem lösen. Die Frage ist nur, wieviel Aufwand dazu notwendig ist.

In der Regel sollten Sie die richtige Schleife für Ihren Zweck wählen, um mit minimalem Aufwand zum Ziel zu kommen. Dazu ist es natür- lich notwendig, einen überblick über die vorhandenen Schleifen zu bekommen.

Schleifentypen

Es gibt prinzipiell drei verschiedene Schleifentypen: abweisende Schleifen, nicht abweisende Schleifen und Zählschleifen. Der Unterschied liegt darin, wann die Schleifen verlassen werden und wann die Bedingung, die das Schleifenende bestimmt, überprüft wird.

Jede Schleife, ausgenommen Endlosschleifen, hat eine Bedingung, die bestimmt, wann die Schleife beendet wlrd. Sie wird Austritts- bzw. Eintrittsbedingung genannt. Bei einer abweisenden Schleife wird die Bedingung geprüft, bevor die Schleife das erste Mal betre- ten wird. Daher wird sie Eintrittsbedingung genannt, sie bestimmt nämlich, ob die Schleife betreten wird.

Jede Schleife, ausgenommen Endlosschleifen, hat eine Bedingung, die bestimmt, wann die Schleife beendet wird. Sie wird Austritts- bzw. Eintrittsbedingung genannt. Bei einer abweisenden Schleife wird die Bedingung geprüft, bevor die Schleife das erste Mal betre- ten wird. Daher wird sie Eintrittsbedingung genannt, sie bestimmt nämlich, ob die Schleife betreten wird.

Bei einer abweisenden Schleife kann es somit passieren, dass die Anweisungen innerhalb der Schleife nie durchlaufen werden. Das ist dann der Fall, wenn die Eintrittsbedingung nie erfüllt ist.

Im Gegensatz dazu werden die Anweisungen einer nicht abweisen- den Schleife immer mindestens einmal durchlaufen, weil erst danach die Austrittsbedingung überprüft wird. Ist sie erfüllt, wird die Schleife verlassen, ansonsten werden die Schleifenanweisungen wiederholt. Zählschleifen haben in der Regel eine Schleifenvariable, die bei jedem Schleifendurchlauf typischerweise um 1 erhöht oder verringert wird (oder um einen anderen Wert). Die Schleife wird so oft ausgeführt, bis der definierte Endwert für die Schleifenvariable erreicht wurde.

Egal, welchen Schleifentyp Sie wählen, müssen Sie darauf achten, dass irgendwann die Schleife korrekt verlassen wird. Andernfalls erhalten Sie eine Endlosschleife, die in der Regel nicht zum gewünschten Ziel führt, da sie nicht verlassen wird und damit ewig zuweisen, die in der Schleifenbedingung verwendet wird, sondern Sie müssen sicherstellen, dass die Schleifenaustrittsbedingung auch tatsächlich irgendwann erfüllt bzw. die Eintrittsbedingung nicht mehr erfüllt ist. Ein gutes Beispiel dafür ist der folgende Code. Scheinbar ist die Schleife zwar korrekt formuliert, trotzdem läuft sie endlos. Das liegt daran, dass die Variable intErg den Anfangs- wert 1 hat und in der Schleife mit sich selbst multipliziert wird. 1 * 1 bleibt aber 1, sodass die Schleifeneintrittsbedingung intErg <=1000 mmer erfüllt bleibt.
  int intErg=1;
  while(intErg<=1000)
  {
     intErg*=intErg;
  }
(Listing 3.35: Fehlerhafte abweisende Schleife)

Abweisende Schleifen

Eine abweisende Schleife wird mit dem Schlüsselwort while eingeleitet. Danach folgt die Eintrittsbedingung, die immer in runde Klammern eingefasst werden muss. Das kann jeder boolesche Ausdruck sein. Die Eintrittsbedingung ist erfüllt, wenn der boolesche Ausdruck wahr ist. In diesem Fall wird die Schleife betreten und ihre Anweisungen werden ausgeführt.

Schleifenkopf, Schleifenfuß und Schleifenrumpf

Jede Schleife setzt sich aus dem Schleifenkopf, dem Schleifenrumpf und dem Schleifenfuß zusammen. Der Schleifenkopf besteht aus dem Schlüsselwort, das die Schleife einleitet, und gegebenenfalls der Ein- trittsbedingung. Der Schleifenrumpf enthält die Anweisungen, die innerhalb der Schleife ausgeführt werden. Der Schleifenfuß schließlich enthält die schließende Klammer und gegebenenfalls eine Austritts- bedingung.

In der abweisenden Schleife besteht der Schleifenkopf also aus dem Schlüsselwort while und der Eintrittsbedingung. Die Anweisungen der Schleife werden wieder in geschweifte Klammern eingefasst. Eine kor- rekt definierte abweisende Schleife könnte also wie folgt lauten:
  int  intErg=2;
  while(intErg<=1000)
  {
     intErg*=intErg;
   }
  MessageBox.Show(intErg.ToString() );
(Listing 3.36: Eine korrekte abweisende Schleife)

Hier wird die Schleife betreten, wenn die Variable intErg kleiner oder gleich 1000 ist. Innerhalb der Schleife wird die Variable mit sich selbst multipliziert und dann wieder der Variablen zugewiesen. Wenn diese Anweisung ausgeführt wurde. ist damit der Schleifenrumpf abgearbei- tet und die Eintrittsbedingung wird erneut geprüft. Wenn die Eintritts- bedingung erfüllt ist, wird der Schleifenrumpf erneut ausgeführt, ansonsten mit der Anweisung nach der Schleife fortgefahren. Hier führt dies zur Ausgabe des Berechnungsergebmsses.

Nicht abweisende Schleifen

Bei den nicht abweisenden Schleifen handelt es sich um solche Schlei- fen, die mindestens einmal durchlaufen werden, weil erst nach Ausfüh- ren des Schleifenrumpfes die Bedingung geprüft wird. Selbst wenn die Austrittsbedingung also schon beim ersten Durchlaufen der Schleife erfüllt ist, werden die Anweisungen im Schleifenrumpf ausgeführt.

In C# werden nicht abweisende Schleifen mit der do-while-Anweisung implementiert. Die Syntax lautet:
  do
  {
  }
  while (boolescher Ausdruck)
Auch hier stehen die Anweisungen des Schleifenrumpfes innerhalb der geschweiften Klammern. Der boolesche Ausdruck stellt die Austrittsbe- dingung dar. Wenn er den Wert false hat, wird die Schleife verlassen. Sie wird also wiederholt, solange der boolesche Ausdruck den Wert true hat.
  intErg=2;
  do
  {
    intErg*=intErg;
  }
  while (intErg <= 1000);
  MessageBox.Show(intErg.ToString() );
(Listing 3.37 Die Berechnung mithilfe einer nicht abweisenden Schleife)"






Back to Top    ↑   (End)