Webpräsenz überarbeitet 👍 👎

Da meine Webpräsenz mit der Zeit doch etwas "gewachsen" ist, habe ich mich dazu entschieden, die Darstellung ein wenig zu überarbeiten. Außerdem gibt es nun zusätzlich zu den Kategorien ein chronologisches Archiv.

Ich hoffe, dass euch die überarbeitete Variante ebenfalls zusagt und freue mich weiterhin über euren Besuch.

Neujahr 👍 👎

Ich bedanke mich für das bisherige Interesse und wünsche ein glückliches und erfolgreiches neues Jahr 2013.

Ich würde mich natürlich sehr darüber freuen, dich auch im nächsten Jahr wieder hier begrüßen zu dürfen.

"??"-Operator in C# 👍 👎

In meinem Beitrag zu NULL für Werttypen in C# hatte ich bereits beschrieben, wie man Werttypen in C# (z. B. bool, int) indirekt dazu bewegen kann, auch null zu akzeptieren, was ansonsten ja nicht möglich ist.

Nun kann es hin und wieder (z. B. zur Arbeit mit externen Bibliotheken) jedoch notwendig sein, diesen Wert einer Variable grundsätzlich gleichen Typs zuzuweisen, die jedoch kein null akzeptiert. Behelfen kann man sich in derartigen Fällen selbstverständlich mit Konstrukten wie diesem:
Zuweisung ohne ??-Operator
010203040506
bool? isValid = null;
bool isRealValid = false;if(isValid.HasValue) { isRealValid = isValid.Value;} // "isRealValid" enthält "false", wenn "isValid" (ebenfalls) "false" oder "null" ist
Etwas kompakter geht es jedoch mit dem ??-Operator (nicht zu verwechseln mit dem ternären ?:-Operator):
Zuweisung mit ??-Operator
01020304
bool? isValid = null;
bool isRealValid = isValid ?? false;// "isRealValid" enthält "false", wenn "isValid" (ebenfalls) "false" oder "null" ist
Der Wert hinter dem Operator dient also als Ersatzwert für null. In beiden Fällen gilt jedoch zu beachten, dass die ursprüngliche Semantik nicht erhalten bleibt. Einem reinen Werttyp kann nun einmal kein null zugewiesen werden, d. h. man muss sich für diesen Fall einen angemessenen Ersatz (z. B. -1 für int) suchen.

Im Übrigen funktioniert das mit beliebigen Referenztypen (deren Wert schließlich immer null sein darf), womit sich beispielsweise bequem Standardobjekte zuweisen lassen:
Standardobjekt per ??-Operator zuweisen
01020304050607080910
/** * "dbUser" soll z. B. aus einer Datenbank * kommen, wurde dort jedoch nicht gefunden.**/User dbUser = null;
User user = dbUser ?? new User() { Nickname = "Gast", IsGuest = true}; // "user" ist ein Gast, wenn "dbUser" auf "null" steht

Mehrdimensionale und verzweigte Felder in C# 👍 👎

Eindimensionale Felder in C# sind schnell eingeführt und verwendet, dazu hatte ich auch schon einmal etwas im Zusammenhang mit PHP geschrieben. Bei den weiteren Varianten des Arrays in C# kann man grundsätzlich zwischen zwei Möglichkeiten unterscheiden: Mehrdimensionale und Verzweigte ("Array von Arrays"). Wir möchten uns daher beide einmal näher ansehen und beginnen zuerst mit dem mehrdimensionalen Feld:
Mehrdimensionales Feld
0102030405
int[,] matrix = new int[,] {    {11,12,13,14,15},    {21,22,23,24,25},    {31,32,33,34,35}};
Während es sich bei eindimensionalen Feldern mathematisch betrachtet um Vektoren handelt, handelt es sich hierbei um eine m*n-Matrix (mit 3 Zeilen und 5 Spalten); analog dazu wären auch dreidimensionale Gebilde etc. möglich. Wichtig zu erkennen ist an dieser Stelle, dass es sich tatsächlich um eine rechteckige Anordnung (nicht jedoch zwangsläufig um eine quadratische) handelt, d. h. jede Zeile besitzt gleich viele Spalten.

Wir können anschließend wie folgt damit arbeiten:
Elemente durchlaufen
0102030405060708091011121314151617181920212223242526272829
  // Verschachtelte Schleifenfor(int m = 0; m < 3; m++) {      // Zeilen    for(int n = 0; n < 5; n++) {  // Spalten        /**         * matrix[m, n] enthält das         * entsprechende Element.        **/    }}
// Einfache Schleifefor(int i = 0; i < matrix.Length; i++) { // matrix.Length = (3 * 5) /** * matrix[i / 5, i % 5] enthält * das entsprechende Element. * * C++-Entwickler mögen an dieser Stelle * an *(*matrix + i) denken, was man bei * C# jedoch nur "unsafe" bekommt. **/}
// FOREACH-Schleifeforeach(int x in matrix) { /** * "x" enthält nun das * entsprechende Element. **/}
Eine weitere Möglichkeit sind nun die sog. verzweigten Felder:
Verzweigtes Feld
0102030405
int[][] data = new int[][] {    new int[] {11,12,13},    new int[] {21,22,23,24},    new int[] {31,32,33,34,35}};
Bereits die Initialisierung verdeutlicht sehr gut, dass es sich wie bereits erwähnt um ein Array von Arrays handelt, wobei jeder Eintrag nun ein Feld "beliebiger" Länge sein kann. Beim Durchlaufen – diesmal im Allgemeinen natürlich nur noch mit verschachtelten Schleifen möglich – wird dies noch einmal dadurch betont, dass wir die entsprechende Length-Eigenschaft (auch) für die innere Schleife nutzen können (und werden):
Elemente durchlaufen
01020304050607080910111213141516171819
  // FOR-Schleifenfor(int i = 0; i < data.Length; i++) {    for(int j = 0; j < data[i].Length; j++) {        /**         * data[i][j] enthält das         * entsprechende Element.        **/    }}
// FOREACH-Schleifenforeach(int[] i in data) { foreach(int j in i) { /** * "j" enthält nun das * entsprechende Element. **/ }}
Derartige Felder werden übrigens oft auch "jagged array" genannt. Zuletzt sei noch erwähnt, dass sich beide Formen durchaus auch kombinieren lassen. Weitere Informationen und Beispiele gibt es wie üblich im MSDN.

Zahl ohne Konvertierung umdrehen 👍 👎

Passend zu einem etwas älteren Beitrag zur Ermittlung der Anzahl der Ziffern einer Zahl soll es noch einmal darum gehen, ein Problem mathematisch zu lösen, statt den Umweg über Zeichenketten zu gehen. Konkret möchten wir eine Zahl schlicht "umdrehen". Im Prinzip soweit natürlich kein Problem:
Zahl umdrehen (mit Konvertierung)
010203
int number = 12345;
int numberReverse = Int32.Parse(String.Concat(number.ToString().Reverse())); // 54321
Wir konvertieren die Zahl hierbei zuerst zu einer Zeichenkette, drehen die Zeichen anschließend um und fügen sie zusammen, um sie letztlich wieder zu einer Zahl zu konvertieren.

Das funktioniert – zumindest bei nicht-negativen Zahlen – soweit auch einwandfrei und kann je nach Kontext auch die schnellste Variante sein, jedoch lässt sich das Problem auch rein rechnerisch lösen:
Zahl umdrehen (ohne Konvertierung)
010203040506070809
int number = 12345;
int numberReverse = 0;while(number != 0) { numberReverse *= 10; numberReverse += (number % 10);
number /= 10;} // "numberReverse" enthält nun (ebenfalls) 54321
Wir nutzen dabei aus, dass uns der Modulo-Operator (%) jeweils den Rest einer ganzzahligen Division liefert, welchen wir als neue Ziffer der Lösung verwenden und anschließend die gegebene Zahl um eben diesen Anteil verringern. Als netter "Nebeneffekt" funktioniert diese Vorgehensweise auch bei negativen Zahlen problemlos.

Projektverweise

Kategorien / Archiv  |  Übersicht RSS-Feed

Schlagworte

Suche