Galileo Computing <openbook>
Galileo Computing - Programming the Net
Galileo Computing - Programming the Net


C# von Eric Gunnerson
Die neue Sprache für Microsofts .NET-Plattform
C# - Zum Katalog
gp Kapitel 15 Operatoren
  gp 15.1 Rangfolge der Operatoren
  gp 15.2 Integrierte Operatoren
  gp 15.3 Benutzerdefinierte Operatoren
  gp 15.4 Numerische Umwandlungen
  gp 15.5 Arithmetische Operatoren
  gp 15.6 Unär Plus (+)
  gp 15.7 Unär Minus (-)
  gp 15.8 Relationale und logische Operatoren
  gp 15.9 Zuweisungsoperatoren
  gp 15.10 Typenoperatoren

Kapitel 15 Operatoren

Die C#-Ausdruckssyntax basiert auf der entsprechenden Syntax von C++.


Galileo Computing

15.1 Rangfolge der Operatoren  downtop

Wenn ein Ausdruck mehrere Operatoren enthält, bestimmt die Rangfolge der Operatoren die Reihenfolge, in der die Elemente des Ausdrucks ausgewertet werden. Die Standardrangfolge kann durch das Setzen von Klammern innerhalb einer Elementegruppe geändert werden.

int    value = 1 + 2 * 3;        // 1 + (2 * 3) 
= 7
       value = (1 + 2) * 3;    // (1 + 2) * 3 = 9

In C# sind alle binären Operatoren links orientiert, d. h., die Operationen werden von links nach rechts ausgeführt. Eine Ausnahme bilden die Zuweisungs- und die Bedingungsoperatoren (?:), die von rechts nach links ausgeführt werden.

In der folgenden Tabelle werden alle Operatoren aufgeführt, die Auflistung fängt hierbei an oberster Stelle an und nimmt hinsichtlich der Vorrangigkeit ab.

Kategorie Operatoren
Primär (x) x.y f(x) a[x] x++ x-- new typeof sizeof checked unchecked
Unär + – ! ~ ++x --x (T)x
Multiplikativ * / %
Additiv + -
Umschaltung << >>
Relational < > <= >= is
Gleichwertigkeit == !=
Logisches AND &
Logisches XOR ^
Logisches OR |
Bedingtes AND &&
Bedingtes OR ||
Bedingung ?:
Zuweisung = *= /= %= += -= <<= >>= &= ^= |=


Galileo Computing

15.2 Integrierte Operatoren  downtop

Bei numerischen Operationen stehen in C# für die Typen int, uint, long, ulong, float, double und decimal integrierte Operatoren zur Verfügung. Da keine integrierten Operatoren für weitere Typen vorhanden sind, müssen Ausdrücke zunächst in einen der vorgenannten Typen konvertiert werden, bevor die Operation ausgeführt werden kann.

Dies bedeutet, dass bei Operationen mit numerischen Typen, die implizit in int konvertiert werden können – die Typen, die »kleiner« sind als int – für das Ergebnis eine Typumwandlung stattfinden muss, damit es im gleichen Typ gespeichert werden kann.

// Fehler
class Test
{
    public static void Main()
    {
        short    s1 = 15;
        short    s2 = 16;
        short ssum = (short) (s1 + s2);    // Typumwandlung erforderlich

        int i1 = 15;
        int i2 = 16;
        int isum = i1 + i2;            // keine Typumwandlung erforderlich
    }
}

Galileo Computing

15.3 Benutzerdefinierte Operatoren  downtop

Benutzerdefinierte Operatoren können für Klassen deklariert werden und weisen die gleiche Funktionsweise auf wie die integrierten Operatoren. Weitere Informationen finden Sie in Kapitel 25, Operatorüberladung.


Galileo Computing

15.4 Numerische Umwandlungen  downtop

Regeln für die numerischen Umwandlungen entnehmen Sie bitte Kapitel 15, Konvertierungen.


Galileo Computing

15.5 Arithmetische Operatoren  downtop

In den folgenden Abschnitten werden die arithmetischen Operationen zusammengefasst, die in C# ausgeführt werden können. Die Gleitkommatypen folgen sehr spezifischen Regeln; detaillierte Informationen hierzu finden Sie in der C#-Sprachreferenz. Bei Ausführung in einem geprüften Kontext können arithmetische Ausdrücke für Nichtgleitkommatypen zu Ausnahmen führen.


Galileo Computing

15.6 Unär Plus (+)  downtop

Bei einem unären Plus handelt es sich bei dem Ergebnis schlicht um den Wert des Operanden.


Galileo Computing

15.7 Unär Minus (-)  downtop

Das unäre Minus funktioniert nur bei Typen, die über eine gültige negative Darstellung verfügen. Der Rückgabewert ist der Wert des Operanden, subtrahiert von Null.


Galileo Computing

15.7.1 Addition (+)  downtop

In C# wird das +-Zeichen sowohl für die Addition als auch für die Zeichenfolgenverkettung verwendet.

Numerische Addition

Die zwei Operanden werden addiert. Wird der Ausdruck in einem geprüften Kontext ausgewertet und liegt die Summe außerhalb des Bereichs für den Ergebnistyp, so wird die Ausnahme OverflowException ausgegeben. Dies wird anhand des folgenden Codes veranschaulicht:

using System;
class Test
{
    public static void Main()
    {
        byte val1 = 200;
        byte val2 = 201;
        byte sum = (byte) (val1 + val2);   // keine Ausnahme
        checked
        {
            byte sum2 = (byte) (val1 + val2);      // Ausnahme

        }
    }
}

Zeichenfolgenverkettung

Zeichenfolgenverkettungen können für zwei Zeichenfolgen oder zwischen einer Zeichenfolge und einem Operanden vom Typ object durchgeführt werden. Weist einer der Operanden den Wert null auf, wird dieser durch eine leere Zeichenfolge ersetzt.

Operanden, die nicht vom Typ string sind, werden durch das Aufrufen der virtuellen ToString()-Methode für das Objekt automatisch in eine Zeichenfolge konvertiert.


Galileo Computing

15.7.2 Subtraktion (-)  downtop

Der zweite Operand wird vom ersten Operanden subtrahiert. Wird der Ausdruck in einem geprüften Kontext ausgewertet und liegt die Differenz außerhalb des Bereichs für den Ergebnistyp, so wird die Ausnahme OverflowException ausgegeben.


Galileo Computing

15.7.3 Multiplikation (*)  downtop

Die zwei Operanden werden multipliziert. Wird der Ausdruck in einem geprüften Kontext ausgewertet und liegt das Ergebnis außerhalb des Bereichs für den Ergebnistyp, so wird die Ausnahme OverflowException ausgegeben.


Galileo Computing

15.7.4 Division (/)  downtop

Der erste Operand wird durch den zweiten Operanden geteilt. Ist der zweite Operand Null, so wird die Ausnahme DivideByZero ausgegeben.


Galileo Computing

15.7.5 Restbetrag (%)  downtop

Das Ergebnis x % y wird berechnet durch x – (x / y) * y. Falls y den Wert Null aufweist, wird die Ausnahme DivideByZero ausgegeben.


Galileo Computing

15.7.6 Umschaltung (<< und >>)  downtop

Für << werden die höherwertigen Bits verworfen und die niederwertigen leeren Bitpositionen auf Null gesetzt.

Für >> mit uint oder ulong werden die niederwertigen Bits verworfen und die höherwertigen leeren Bitpositionen auf Null gesetzt.

Für >> mit int oder long werden die niederwertigen Bits verworfen. Ist x nicht positiv, werden die höherwertigen leeren Bitpositionen auf Null gesetzt, ist x positiv, werden die höherwertigen leeren Bitpositionen auf 1 gesetzt.


Galileo Computing

15.7.7 Wertezuwachs und -abname (++ und --)  downtop

Der Zuwachsoperator erhöht den Wert einer Variablen um 1, der Abnahmeoperator vermindert den Wert der Variablen um 1.

Die Operatoren für den Wertezuwachs und die Werteabnahme können als Präfixoperator (die Variable wird vor dem Lesen geändert) oder als Suffixoperator verwendet werden (der Wert wird vor der Änderung zurückgegeben).

Beispiel:

int    k = 5;
int    value = k++;    // Wert beträgt 5
       value = --k;    // Wert beträgt weiterhin 5
       value = ++k;    // Wert beträgt 6

Galileo Computing

15.8 Relationale und logische Operatoren  downtop

Relationale Operatoren werden für den Vergleich zweier Werte eingesetzt, mit logischen Operatoren werden bitweise Operationen für Werte ausgeführt.


Galileo Computing

15.8.1 Logische Negation (!)  downtop

Über den !-Operator kann die Negation eines booleschen Wertes zurückgegeben werden.


Galileo Computing

15.8.2 Relationale Operatoren  downtop

C# definiert die folgenden relationalen Operationen:

Operation Beschreibung
a == b wahr, wenn a gleich b
a != b wahr, wenn a ungleich b
a < b wahr, wenn a kleiner b
a <= b wahr, wenn a kleiner gleich b
a > b wahr, wenn a größer b
a >= b wahr, wenn a größer gleich b

Diese Operatoren geben ein Ergebnis vom Typ bool zurück.

Beim Vergleich zweier Verweistypobjekte sucht der Compiler zunächst nach relationalen Operatoren für die Objekte. Wird kein anwendbarer Operator ermittelt und lautet die Relation == oder !==, wird der geeignete relationale Operator von der Objektklasse aufgerufen. Dieser Operator prüft, ob es sich bei den beiden Operanden um das gleiche Objekt handelt, nicht aber, ob sie den gleichen Wert aufweisen.

Bei Wertetypen ist das Verfahren ebenso, abgesehen davon, dass der integrierte Operator für Wertetypen jedes der Felder im struct überprüft und ein true zurückgibt, wenn alle Werte identisch sind.

Für den Typ string werden die relationalen Operatoren überladen, sodass mit == und !== die Werte der Zeichenfolgen verglichen werden, nicht aber die Verweise.


Galileo Computing

15.8.3 Logische Operatoren  downtop

C# definiert die folgenden logischen Operatoren:

Operator Beschreibung
& Bitweises AND der zwei Operanden
| Bitweises OR der zwei Operanden
^ Bitweises exklusives OR (XOR) der zwei Operanden
&& Logisches AND der zwei Operanden
|| Logisches OR der zwei Operanden

Die Operatoren &, | und ^ werden üblicherweise für integer-Datentypen verwendet, obwohl sie auch auf bool-Typen angewendet werden können.

Die Operatoren && und || unterscheiden sich von den Einzelzeichenversionen darin, dass sie eine Umgehungsauswertung durchführen. Im Ausdruck

a && b

wird b nur ausgewertet, wenn a wahr (true) ist. Im Ausdruck

a || b

wird b nur ausgewertet, wenn a unwahr (false) ist.


Galileo Computing

15.8.4 Bedingungsoperator (?:)  downtop

Gelegentlich auch Ternär- oder Frageoperator genannt. Dieser Bedingungsoperator wählt basierend auf einem booleschen Ausdruck aus zwei Ausdrücken aus.

int    value = (x < 10) ? 15 : 5;

In diesem Beispiel wird der Steuerungsausdruck (x < 10) ausgewertet. Ist dieser wahr, dann ist der Operatorwert der erste Ausdruck nach dem Fragezeichen, in diesem Fall 15. Ist der Steuerungsausdruck falsch, dann ist der Operatorwert der Ausdruck nach dem Doppelpunkt, hier 5.


Galileo Computing

15.9 Zuweisungsoperatoren  downtop

Zuweisungsoperatoren werden zur Zuweisung eines Wertes zu einer Variablen eingesetzt. Es gibt zwei Formen: die einfache Zuweisung und die komplexe Zuweisung.


Galileo Computing

15.9.1 Einfache Zuweisung  downtop

Die einfache Zuweisung erfolgt in C# mit dem einfachen Gleichheitszeichen =. Damit die Zuordnung erfolgreich verläuft, muss die rechte Seite der Zuordnung einen Typ aufweisen, der implizit in den Variablentyp der linken Zuordnungsseite konvertiert werden kann.


Galileo Computing

15.9.2 Komplexe Zuweisung  downtop

Die Operatoren für die komplexe Zuweisung führen neben der einfachen Zuordnung weitere Operationen aus. Die zugehörigen Operatoren lauten:

+= -= *= /= %= &= |= ^= <<= >>=

Der Operator

x <op>= y

wird exakt so ausgewertet, als würde er folgendermaßen ausgedrückt:

x = x <op> y

Hierbei gelten zwei Ausnahmen:

gp  x wird nur einmal ausgewertet, und die Auswertung wird sowohl für die Operation als auch für die Zuweisung verwendet.
gp  Wenn x einen Funktionsaufruf oder Arrayverweise enthält, wird es nur einmal ausgeführt.

Nach den normalen Konvertierungsregeln und unter der Voraussetzung, dass x und y beides short-Ganzzahlen sind, führt das Auswerten von

x = x + 3;

zu einem Kompilierungsfehler, da die Addition für int-Werte ausgeführt wird, das int-Ergebnis jedoch nicht implizit in einen short-Wert konvertiert wird. In diesem Fall jedoch, da short implizit in int konvertiert werden kann und folgende Schreibweise möglich ist

x = 3;

ist die Operation erlaubt.


Galileo Computing

15.10 Typenoperatoren  downtop

Die Typenoperatoren beschäftigen sich nicht mit den Werten eines Objekts, sondern mit deren Typen.


Galileo Computing

15.10.1 Typeof  downtop

Der typeof-Operator gibt den Typ des Objekts zurück, eine Instanz der Klasse System.Type. Typeof ist nützlich, da so nicht erst eine Objektinstanz erstellt werden muss, nur um das type-Objekt zu erhalten. Ist bereits eine Instanz vorhanden, kann durch Aufruf der Funktion GetType() für die Instanz das type-Objekt abgerufen werden.

Nachdem das type-Objekt für einen Typ vorhanden ist, können über die Reflektion weitere Typinformationen abgerufen werden. Weitere Informationen zu diesem Thema finden Sie in Kapitel 31, C# im Detail, im Abschnitt »Weitergehende Reflektion«.


Galileo Computing

15.10.2 Is  downtop

Mit dem is-Operator wird ermittelt, ob ein Objektverweis in einen spezifischen Typ oder eine Schnittstelle konvertiert werden kann. Sehr häufig wird mit diesem Operator ermittelt, ob ein Objekt eine bestimmte Schnittstelle unterstützt.

using System;
interface IAnnoy
{
    void PokeSister(string name);
}
class Brother: IAnnoy
{
    public void PokeSister(string name)
    {
        Console.WriteLine("Poking {0}", name);
    }
}
class BabyBrother
{
}
class Test
{
    public static void AnnoyHer(string sister, params object[] annoyers)
    {
        foreach (object o in annoyers)
        {
            if (o is IAnnoy)
            {
                IAnnoy annoyer = (IAnnoy) o;
                annoyer.PokeSister(sister);
            }
        }
    }
    public static void Main()
    {
        Test.AnnoyHer("Jane", new Brother(), new BabyBrother());
    }
}

Dieser Code erzeugt die folgende Ausgabe:

Poking: Jane

In diesem Beispiel implementiert die Klasse Brother die Schnittstelle IAnnoy, die Klasse BabyBrother implementiert diese Schnittstelle nicht. Die Funktion AnnoyHer() durchläuft alle ihr übergebenen Objekte, um zu ermitteln, ob eines der Objekte IAnnoy unterstützt. Unterstützt das Objekt die Schnittstelle, wird die Funktion PokeSister() aufgerufen.


Galileo Computing

15.10.3 As  toptop

Der as-Operator ähnelt dem is-Operator, hier wird jedoch nicht nur geprüft, ob es sich bei dem Objekt um einen spezifischen Typ oder eine Schnittstelle handelt, es wird auch eine explizite Konvertierung in diesen Typ oder die Schnittstelle durchgeführt. Kann das Objekt nicht in diesen Typ oder die Schnittstelle konvertiert werden, gibt der Operator null zurück. Das Verwenden von as ist effizienter als die Verwendung von is, da der as-Operator den Objekttyp nur einmal prüft, beim is-Operator wird der Typ dagegen einmal bei der Operatorverwendung und bei der Konvertierung ein zweites Mal geprüft.

Im vorangegangenen Beispiel können die Zeilen

            if (o is IAnnoy)
            {
                IAnnoy annoyer = (IAnnoy) o;
                annoyer.PokeSister(sister);
            }

durch diese ersetzt werden:

            IAnnoy annoyer = o as IAnnoy;
            if (Annoyer != null)
                annoyer.PokeSister(sister);





1    Diese Regeln entsprechen IEEE 754.

2    Da jeder Typ in ein Objekt konvertiert werden kann, sind beliebige Typen möglich.

3    Im unsafe-Modus werden Zeiger um die Größe des referenzierten Objekts erhöht oder erniedrigt.

   

Select * from SQL Server 2000




Copyright © Galileo Press GmbH 2001 - 2002
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Galileo Computing]

Galileo Press GmbH, Gartenstraße 24, 53229 Bonn, fon: 0228.42150.0, fax 0228.42150.77, info@galileo-press.de