C# Basics Teil 1

In den ersten paar Artikeln werde ich mich mit den C# Basics befassen. Dabei versuche ich nur auf Spezialitäten einzugehen, die man im Altag gerne vergisst – jedoch in bestimmten Situationen sehr hilfreich sein können.

Der checked/unchecked operator

Mit dem checked/unchecked Operator kann das Verhalten bei arithmetischen Überläufen definiert werden. Der Operator kann entweder als Expression oder Statement Block benutzt werden.

checked(<expression>) oder checked { /* statements */ }

Beispiel:

int a = int.MaxValue;
int b = a + 1; // b = -2147483648
b = checked(a + 1); // OverflowException
b = unchecked(a + 1); // b = -2147483648, auch mit Kompiler-Option /checked
b = int.MaxValue + 1; // Compiler-Error
b = unchecked(int.MaxValue + 1); // Kein Compiler-Error

Der params Parameter Modifier

Der params Parameter Modifier kann an einen letzten Parameter von einer Methode definiert werden. Der entsprechende Parameter muss jedoch vom Typ Array (z.B. int[]) sein. Der Compiler kann dann die letzten aktuellen Parameter in einen formalen Array-Parameter umwandeln.

Beispiel:

private int Sum(params int[] values)
{
int sum = 0;
foreach (int i in values)
sum += i;
return sum;
}

private void Calculate()
{
int sum = this.Sum(10, 44, 278);  // wird vom Compiler in int[] umgewandelt
sum = this.Sum(new int[] { 10, 44, 278 }); // Aufruf ohne params modifier
}

Boxing und Unboxing

Boxing und unboxing ist recht schnell erklärt. Boxing wird die Aktion genannt, wenn ein Value-type in einen Reference-type gecastet werden muss resp. ungekehrt.

Beispiel:

int x = 10;
object o = x;   // boxing
int b = (int)o; // unboxing

Schlüsselwort Unsafe

Ausführen von Programcode, welcher nicht durch die CRL kontrolliert wird. Damit lässt sich performanteren Code generieren, der weniger Overhead produziert. Doch er ist auch gefährlich und sollte nur in wenigen speziellen Bereichen verwendet werden. Ein weiterer Vorteil davon ist, dass man besser mit anderem unmanaged Code kommunizieren kann.

Beispiel:

unsafe // Kann nur mit Kompileranweisung /unsafe benutzt werden
{
int x = 10;
int* p = &x; // Adresse von x in den int-pointer p speichern (Referenzierung)
int y = *p;  // Wert an Adresse des int-pointers p in y speichern (Dereferenzierung)
p->CompareTo(y);   // Methodenaufruf direkt auf dem Pointer
(*p).CompareTo(y); // Methodenaufruf auf dem dereferenzierten Objekt
}

Noch ein paar Randbemerkungen

Der Adress-Operator „&“ ist nur bei Value-Typs notwendig, da es sich bei Referenz-Typen ja bereits um Referenzen handelt.

An die Adressen von Referenz-Typen kann man nicht so ohne weiteres kommen, da diese vom Garbage Collector aus Gründen der Effizienz immer wieder hin und her bewergt werden. Um sie zu verwenden muss man mit dem fixed-Statement arbeiten. Mehr dazu in einem späteren Artikel.