Freigeben über


Operatoren zur Typprüfung und Cast-Ausdrücke - is, as, typeof, and casts

Diese Operatoren und Ausdrücke führen eine Typüberprüfung oder Typkonvertierung durch. Der is-Operator überprüft, ob der Laufzeittyp eines Ausdrucks mit einem angegebenen Typ kompatibel ist. Der as-Operator konvertiert einen Ausdruck explizit in einen angegebenen Typ, wenn der Laufzeittyp mit diesem Typ kompatibel ist. Cast expressions eine explizite Konvertierung in einen Zieltyp durchführen. Der typeof-Operator ruft die System.Type-Instanz für einen Typ ab.

Den is-Operator

Der is-Operator prüft, ob der Laufzeittyp eines Ausdrucksergebnisses mit einem angegebenen Typ kompatibel ist. Der is-Operator überprüft ein Ausdrucksergebnis auch anhand eines Musters.

Der Ausdruck mit dem is-Operator für die Typüberprüfung weist folgende Form auf:

E is T

Dabei E handelt es sich um einen Ausdruck, der einen Wert zurückgibt und T der Name eines Typs oder eines Typparameters ist. E kann keine anonyme Methode oder ein Lambda-Ausdruck sein.

Der is-Operator gibt true zurück, wenn ein Ausdrucksergebnis nicht NULL ist und eine der folgenden Bedingungen erfüllt ist:

  • Der Laufzeittyp eines Ausdrucksergebnisses hat eine Identitätskonvertierung nach T.

  • Der Laufzeittyp eines Ausdrucksergebnisses wird vom Typ T abgeleitet, oder er implementiert die T-Schnittstelle, oder es gibt eine andere implizite Verweiskonvertierung von diesem Typ zu T. Dies umfasst Vererbungsbeziehungen und Schnittstellenimplementierungen.

  • Der Laufzeittyp eines Ausdrucksergebnisses ist ein Nullwerte zulassender Wert mit dem zugrunde liegenden Typ T und Nullable<T>.HasValue ist true.

  • A boxing or unboxing Konvertierung existiert vom Laufzeittyp eines Ausdrucksergebnisses zum Typ T , wenn der Ausdruck keine Instanz eines ref struct.

Der is Operator berücksichtigt keine benutzerdefinierten Konvertierungen oder implizite Span-Konvertierungen.

Das folgende Beispiel zeigt, dass der is-Operator true zurückgibt, wenn der Laufzeittyp eines Ausdrucksergebnisses von einem angegebenen Typ abgeleitet ist, wenn also eine Verweiskonvertierung zwischen Typen besteht:

public class Base { }

public class Derived : Base { }

public static class IsOperatorExample
{
    public static void Main()
    {
        object b = new Base();
        Console.WriteLine(b is Base);  // output: True
        Console.WriteLine(b is Derived);  // output: False

        object d = new Derived();
        Console.WriteLine(d is Base);  // output: True
        Console.WriteLine(d is Derived); // output: True
    }
}

Das nächste Beispiel zeigt, dass der is-Operator Boxing- und Unboxingkonvertierungen berücksichtigt, numerische Konvertierungen aber nicht:

int i = 27;
Console.WriteLine(i is System.IFormattable);  // output: True

object iBoxed = i;
Console.WriteLine(iBoxed is int);  // output: True
Console.WriteLine(iBoxed is long);  // output: False

Informationen zu C#-Konvertierungen finden Sie im Kapitel Konvertierungen der C#-Sprachspezifikation.

Typüberprüfung mit Musterabgleich

Der is-Operator überprüft ein Ausdrucksergebnis auch anhand eines Musters. Im folgenden Beispiel wird gezeigt, wie ein Deklarationsmuster verwendet wird, um den Laufzeittyp eines Ausdrucks zu überprüfen:

int i = 23;
object iBoxed = i;
int? jNullable = 7;
if (iBoxed is int a && jNullable is int b)
{
    Console.WriteLine(a + b);  // output 30
}

Informationen zu den unterstützten Mustern finden Sie unter Muster.

Den as-Operator

Der as-Operator konvertiert das Ergebnis eines Ausdrucks explizit in einen angegebenen Verweis- oder Nullable-Typ. Wenn die Konvertierung nicht möglich ist, gibt der as-Operator null zurück. Im Gegensatz zum Cast-Ausdruck löst der as-Operator nie eine Ausnahme aus.

Sehen Sie sich diesen Ausdruck an:

E as T

Dabei E handelt es sich um einen Ausdruck, der einen Wert zurückgibt und T der Name eines Typs oder eines Typparameters ist, dasselbe Ergebnis wie

E is T ? (T)(E) : (T)null

Mit der Ausnahme, dass E nur einmal ausgewertet wird.

Der as-Operator berücksichtigt nur Verweis-, Nullable-, Boxing- und Unboxingkonvertierungen. Sie können den as-Operator nicht verwenden, um eine benutzerdefinierte Konvertierung auszuführen. Verwenden Sie hierzu einen Cast-Ausdruck.

Im folgenden Beispiel wird die Verwendung des as-Operators veranschaulicht:

IEnumerable<int> numbers = new List<int>(){10, 20, 30};
IList<int> indexable = numbers as IList<int>;
if (indexable != null)
{
    Console.WriteLine(indexable[0] + indexable[indexable.Count - 1]);  // output: 40
}

Hinweis

Wie im vorherigen Beispiel gezeigt, müssen Sie das Ergebnis des as Ausdrucks mit null vergleichen, um zu überprüfen, ob die Konvertierung erfolgreich war. Sie können den is Operator verwenden, um zu testen, ob die Konvertierung erfolgreich ist, und wenn sie erfolgreich ist, das Ergebnis einer neuen Variablen zuzuweisen.

Cast-Ausdruck

Ein cast-Ausdruck der Form (T)E führt eine explizite Konvertierung des Ergebnisses des Ausdrucks E in den Typ T durch. Wenn keine explizite Konvertierung von Typ E in Typ T möglich ist, tritt ein Fehler während der Kompilierung auf. Möglicherweise ist eine explizite Konvertierung zur Laufzeit nicht erfolgreich, und ein cast-Ausdruck löst eine Ausnahme aus.

Das folgende Beispiel zeigt explizite numerische und Verweiskonvertierungen:

double x = 1234.7;
int a = (int)x;
Console.WriteLine(a);   // output: 1234

int[] ints = [10, 20, 30];
IEnumerable<int> numbers = ints;
IList<int> list = (IList<int>)numbers;
Console.WriteLine(list.Count);  // output: 3
Console.WriteLine(list[1]);  // output: 20

Informationen zu expliziten Konvertierungen finden Sie im Abschnitt Explizite Konvertierungen der C#-Sprachspezifikation. Informationen zum Definieren einer benutzerdefinierten expliziten oder impliziten Typkonvertierung finden Sie unter Benutzerdefinierte Konvertierungsoperatoren.

Andere Verwendungen von „()“

Sie verwenden Klammern auch zum Aufrufen einer Methode oder eines Delegaten.

Mit Klammern können Sie auch die Reihenfolge anpassen, in der Vorgänge in einem Ausdruck ausgewertet werden sollen. Weitere Informationen finden Sie unter C#-Operatoren.

Den typeof-Operator

Der typeof-Operator ruft die System.Type-Instanz für einen Typ ab. Das Argument für den typeof-Operator muss der Name eines Typs oder Typparameters sein, wie das folgende Beispiel zeigt:

void PrintType<T>() => Console.WriteLine(typeof(T));

Console.WriteLine(typeof(List<string>));
PrintType<int>();
PrintType<System.Int32>();
PrintType<Dictionary<int, char>>();
// Output:
// System.Collections.Generic.List`1[System.String]
// System.Int32
// System.Int32
// System.Collections.Generic.Dictionary`2[System.Int32,System.Char]

Das Argument darf kein Typ sein, der Metadatenanmerkungen erfordert. Die Beispiele umfassen die folgenden Typen:

  • dynamic
  • string? (oder einem beliebigen nullbaren Referenztyp)

Diese Typen werden nicht direkt in Metadaten dargestellt. Die Typen enthalten Attribute, die den zugrunde liegenden Typ beschreiben. In beiden Fällen können Sie den zugrunde liegenden Typen verwenden. Statt dynamic können Sie object verwenden. Statt string? können Sie string verwenden.

Sie können den typeof-Operator auch mit ungebundenen generischen Typen verwenden. Der Name eines ungebundenen generischen Typs muss die entsprechende Anzahl von Kommas enthalten: eines weniger als die Anzahl von Typparametern. Das folgende Beispiel zeigt die Verwendung des typeof-Operators mit einem ungebundenen generischen Typ:

Console.WriteLine(typeof(Dictionary<,>));
// Output:
// System.Collections.Generic.Dictionary`2[TKey,TValue]

Ein Ausdruck kann kein Argument des typeof-Operators sein. Verwenden Sie die System.Type-Methode, um die Object.GetType-Instanz für den Laufzeittyp eines Ausdrucksergebnisses abzurufen.

Typüberprüfung mit dem typeof-Operator

Verwenden Sie den typeof-Operator, um zu überprüfen, ob der Laufzeittyp des Ausdrucksergebnisses exakt mit einem angegebenen Typ übereinstimmt. Im folgenden Beispiel wird der Unterschied zwischen der Typüberprüfung mit dem typeof Operator und dem is Operator veranschaulicht:

public class Animal { }

public class Giraffe : Animal { }

public static class TypeOfExample
{
    public static void Main()
    {
        object b = new Giraffe();
        Console.WriteLine(b is Animal);  // output: True
        Console.WriteLine(b.GetType() == typeof(Animal));  // output: False

        Console.WriteLine(b is Giraffe);  // output: True
        Console.WriteLine(b.GetType() == typeof(Giraffe));  // output: True
    }
}

Operatorüberladbarkeit

Die Operatoren is, as und typeof können nicht überladen werden.

Ein benutzerdefinierter Typ kann den () -Operator nicht überladen, kann aber benutzerdefinierte Typkonvertierungen definieren, die durch einen Cast-Ausdruck durchgeführt werden. Weitere Informationen finden Sie unter Benutzerdefinierte Konvertierungsoperatoren.

C#-Sprachspezifikation

Weitere Informationen finden Sie in den folgenden Abschnitten der C#-Sprachspezifikation:

Weitere Informationen