is (C#-Referenz)is (C# Reference)

Der is-Operator überprüft, ob das Ergebnis eines Ausdrucks mit einem angegebenen Typ kompatibel ist, oder (ab C# 7.0) testet einen Ausdruck anhand eines Musters.The is operator checks if the result of an expression is compatible with a given type, or (starting with C# 7.0) tests an expression against a pattern. Informationen zu Typtests des is-Operators finden Sie im Abschnitt is-Operator des Artikels Typtestoperatoren und Cast-Ausdrücke.For information about the type-testing is operator, see the is operator section of the Type-testing and cast operators article.

Musterabgleich mit isPattern matching with is

Ab C# 7.0 unterstützen die Anweisungen is und switch den Musterabgleich.Starting with C# 7.0, the is and switch statements support pattern matching. Das Schlüsselwort is unterstützt folgende Muster:The is keyword supports the following patterns:

  • Das Typmuster, das prüft, ob ein Ausdruck in einen angegebenen Typ konvertiert werden kann, und die Variable, sofern die Konvertierung möglich ist, in eine Variable dieses Typs umwandelt.Type pattern, which tests whether an expression can be converted to a specified type and, if it can be, casts the variable to a variable of that type.
  • Das Konstantenmuster, das prüft, ob ein Ausdruck einen angegebenen konstanten Wert ergibt.Constant pattern, which tests whether an expression evaluates to a specified constant value.
  • Das Variablenmuster, eine Übereinstimmung, die immer erfolgreich ausführt wird und den Wert eines Ausdrucks an eine neue lokale Variable bindet.var pattern, a match that always succeeds and binds the value of an expression to a new local variable.

TypmusterType pattern

Wenn Sie das Typmuster verwenden, um einen Musterabgleich durchzuführen, prüft is, ob ein Ausdruck in einen angegebenen Typen konvertiert werden kann; sofern dies möglich ist, wandelt es diesen in eine Variable dieses Typ um.When using the type pattern to perform pattern matching, is tests whether an expression can be converted to a specified type and, if it can be, casts it to a variable of that type. Dies ist eine einfach Erweiterung der is-Anweisung, die eine präzise Auswertung und Konvertierung des Typs ermöglicht.It's a straightforward extension of the is statement that enables concise type evaluation and conversion. Die allgemeine Form des Typmusters is ist:The general form of the is type pattern is:

expr is type varname

Hier ist expr ein Ausdruck, der eine Instanz eines beliebigen Typen ergibt, Typ ist der Name des Typen, in den das Ergebnis von expr konvertiert werden soll, und varname ist das Objekt, in das das Ergebnis von expr konvertiert wird, wenn der is-Test true ist.Where expr is an expression that evaluates to an instance of some type, type is the name of the type to which the result of expr is to be converted, and varname is the object to which the result of expr is converted if the is test is true.

Der Ausdruck is ist true, wenn expr nicht null ist und eine der folgenden Bedingungen vorliegt:The is expression is true if expr isn't null, and any of the following conditions is true:

  • expr ist eine Instanz des gleichen Typs wie Typ.expr is an instance of the same type as type.
  • expr ist eine Instanz eines Typs, der von Typ abgeleitet wird.expr is an instance of a type that derives from type. Das Ergebnis von expr kann, in anderen Worten, in eine Instanz von Typ umgewandelt werden.In other words, the result of expr can be upcast to an instance of type.
  • expr hat einen Kompilierzeittyp, der eine Basisklasse von type ist, und expr hat einen Laufzeittyp,der type ist oder von type abgeleitet wurde.expr has a compile-time type that is a base class of type, and expr has a runtime type that is type or is derived from type. Der Kompilierzeittyp einer Variablen ist der Typ der Variablen, wie in der Deklaration des Typs definiert.The compile-time type of a variable is the variable's type as defined in its declaration. Der Laufzeittyp einer Variablen ist der Typ der Instanz, die dieser Variable zugewiesen wird.The runtime type of a variable is the type of the instance that is assigned to that variable.
  • expr ist eine Instanz eines Typs, der die Schnittstelle Typ implementiert.expr is an instance of a type that implements the type interface.

Beginnend mit C# 7.1 kann expr einen Kompilierzeittyp haben, der durch einen generischen Typparameter und seine Einschränkungen definiert ist.Beginning with C# 7.1, expr may have a compile-time type defined by a generic type parameter and its constraints.

Wenn exprtrue ist und is mit der if-Anweisung verwendet wird, wird varname nur innerhalb der if-Anweisung zugewiesen.If expr is true and is is used with an if statement, varname is assigned within the if statement only. Der Bereich von varname stammt aus dem is-Ausdruck am Ende des Block, der die if-Anweisung umschließt.The scope of varname is from the is expression to the end of the block enclosing the if statement. Bei Verwendung von varname an einer anderen Stelle wird ein Kompilierzeitfehler für die Verwendung einer nicht zugewiesenen Variablen erzeugt.Using varname in any other location generates a compile-time error for use of a variable that hasn't been assigned.

Im folgenden Beispiel wird das is-Typmuster verwendet, um die Implementierung der Methode IComparable.CompareTo(Object) des Typs bereitzustellen.The following example uses the is type pattern to provide the implementation of a type's IComparable.CompareTo(Object) method.

using System;

public class Employee : IComparable
{
    public String Name { get; set; }
    public int Id { get; set; }

    public int CompareTo(Object o)
    {
        if (o is Employee e)
        {
            return Name.CompareTo(e.Name);
        }
        throw new ArgumentException("o is not an Employee object.");
    }
}

Ohne Musterabgleich könnte dieser Code wie folgt geschrieben werden.Without pattern matching, this code might be written as follows. Die Verwendung des Typenmusterabgleichs erzeugt einen kompakteren, lesbaren Code, da nicht mehr geprüft werden muss, ob das Ergebnis einer Umwandlung null ist.The use of type pattern matching produces more compact, readable code by eliminating the need to test whether the result of a conversion is a null.

using System;

public class Employee : IComparable
{
    public String Name { get; set; }
    public int Id { get; set; }

    public int CompareTo(Object o)
    {
        var e = o as Employee;
        if (e == null)
        {
           throw new ArgumentException("o is not an Employee object.");
        }
        return Name.CompareTo(e.Name);
    }
}

Das Typmuster is erstellt zusätzlich kompakteren Code, wenn der Typ eines Werttyps bestimmt wird.The is type pattern also produces more compact code when determining the type of a value type. Im folgenden Beispiel wird das Typmuster is verwendet, um zu bestimmen, ob ein Objekt eine Instanz von Person oder Dog ist, bevor der Wert einer passenden Eigenschaft angezeigt wird.The following example uses the is type pattern to determine whether an object is a Person or a Dog instance before displaying the value of an appropriate property.

using System;

public class Example
{
   public static void Main()
   {
      Object o = new Person("Jane");
      ShowValue(o);

      o = new Dog("Alaskan Malamute");
      ShowValue(o);
   }

   public static void ShowValue(object o)
   {
      if (o is Person p) {
         Console.WriteLine(p.Name);
      }
      else if (o is Dog d) {
         Console.WriteLine(d.Breed);
      }
   }
}

public struct Person
{
   public string Name { get; set; }

   public Person(string name) : this()
   {
      Name = name;
   }
}

public struct Dog
{
   public string Breed { get; set; }

   public Dog(string breedName) : this()
   {
      Breed = breedName;
   }
}
// The example displays the following output:
//	Jane
//	Alaskan Malamute

Der gleichwertige Code erfordert ohne einen Musterabgleich eine gesonderte Zuweisung, die eine explizite Umwandlung beinhaltet.The equivalent code without pattern matching requires a separate assignment that includes an explicit cast.

using System;

public class Example
{
   public static void Main()
   {
      Object o = new Person("Jane");
      ShowValue(o);

      o = new Dog("Alaskan Malamute");
      ShowValue(o);
   }

   public static void ShowValue(object o)
   {
      if (o is Person) {
         Person p = (Person) o;
         Console.WriteLine(p.Name);
      }
      else if (o is Dog) {
         Dog d = (Dog) o;
         Console.WriteLine(d.Breed);
      }
   }
}

public struct Person
{
   public string Name { get; set; }

   public Person(string name) : this()
   {
      Name = name;
   }
}

public struct Dog
{
   public string Breed { get; set; }

   public Dog(string breedName) : this()
   {
      Breed = breedName;
   }
}
// The example displays the following output:
//       Jane
//       Alaskan Malamute

KonstantenmusterConstant pattern

Beim Durchführen eines Musterabgleichs mit einem Konstantenmuster prüft is, ob ein Ausdruck einer angegebenen Konstanten entspricht.When performing pattern matching with the constant pattern, is tests whether an expression equals a specified constant. In C# 6 und früheren Versionen wird das Konstantenmuster von der Anweisung switch unterstützt.In C# 6 and earlier versions, the constant pattern is supported by the switch statement. Ab C# 7.0 wird es ebenfalls von der Anweisung is unterstützt.Starting with C# 7.0, it's supported by the is statement as well. Die Syntax sieht wie folgt aus:Its syntax is:

   expr is constant

Hier ist expr der auszuwertende Ausdruck, und constant ist der Wert, auf den geprüft werden soll.where expr is the expression to evaluate, and constant is the value to test for. constant kann eine der folgenden konstanten Ausdrücke sein:constant can be any of the following constant expressions:

  • Ein LiteralwertA literal value.

  • Der Name einer deklarierten const-VariablenThe name of a declared const variable.

  • Eine Enumerationskonstante.An enumeration constant.

Der Konstantenausdruck wird wie folgt ausgewertet:The constant expression is evaluated as follows:

  • Wenn expr und constant integrale Typen sind, bestimmt der C#-Gleichheitsoperator, ob der Ausdruck true (d.h., ob expr == constant) zurückgibt.If expr and constant are integral types, the C# equality operator determines whether the expression returns true (that is, whether expr == constant).

  • Andernfalls wird der Wert des Ausdrucks durch einen Aufruf der statischen Methode Object.Equals (expr, constant) bestimmt.Otherwise, the value of the expression is determined by a call to the static Object.Equals(expr, constant) method.

Im folgenden Beispiel werden Typ- und Konstantenmuster miteinander vereint, um zu prüfen, ob ein Objekt eine Dice-Instanz ist; ist dem so, wird geprüft, ob der Wert eines Würfelvorgangs 6 ist.The following example combines the type and constant patterns to test whether an object is a Dice instance and, if it is, to determine whether the value of a dice roll is 6.

using System;

public class Dice
{
    Random rnd = new Random();
    public Dice()
    {
    }
    public int Roll()
    {
        return rnd.Next(1, 7);
    }
}

class Program
{
    static void Main(string[] args)
    {
        var d1 = new Dice();
        ShowValue(d1);
    }

    private static void ShowValue(object o)
    {
        const int HIGH_ROLL = 6;

        if (o is Dice d && d.Roll() is HIGH_ROLL)
            Console.WriteLine($"The value is {HIGH_ROLL}!");
        else
            Console.WriteLine($"The dice roll is not a {HIGH_ROLL}!");
     }
}
// The example displays output like the following:
//      The value is 6!

Die Überprüfung auf null kann mithilfe des Konstantenmusters erfolgen.Checking for null can be performed using the constant pattern. Das Schlüsselwort null wird von der is-Anweisung unterstützt.The null keyword is supported by the is statement. Die Syntax sieht wie folgt aus:Its syntax is:

   expr is null

Das folgende Beispiel zeigt einen Vergleich von null-Überprüfungen:The following example shows a comparison of null checks:

using System;

class Program
{
    static void Main(string[] args)
    {
        object o = null;

        if (o is null)
        {
            Console.WriteLine("o does not have a value");
        }
        else
        {
            Console.WriteLine($"o is {o}");
        }

        int? x = 10;

        if (x is null)
        {
            Console.WriteLine("x does not have a value");
        }
        else
        {
            Console.WriteLine($"x is {x.Value}");
        }

        // 'null' check comparison
        Console.WriteLine($"'is' constant pattern 'null' check result : { o is null }");
        Console.WriteLine($"object.ReferenceEquals 'null' check result : { object.ReferenceEquals(o, null) }");
        Console.WriteLine($"Equality operator (==) 'null' check result : { o == null }");
    }

    // The example displays the following output:
    // o does not have a value
    // x is 10
    // 'is' constant pattern 'null' check result : True
    // object.ReferenceEquals 'null' check result : True
    // Equality operator (==) 'null' check result : True
}

Der Ausdruck x is null wird für Referenztypen und Nullwerte zulassende Werttypen unterschiedlich berechnet.The expression x is null is computed differently for reference types and nullable value types. Für Nullwerte zulassende Werttypen wird Nullable<T>.HasValue verwendet.For nullable value types, it uses Nullable<T>.HasValue. Für Referenztypen wird (object)x == null verwendet.For reference types, it uses (object)x == null.

var-Mustervar pattern

Eine Musterübereinstimmung mit einem var-Muster wird immer erfolgreich ausgeführt.A pattern match with the var pattern always succeeds. Die Syntax sieht wie folgt aus:Its syntax is:

   expr is var varname

Hier wird der Wert von expr immer einer lokalen Variablen mit dem Namen varname zugewiesen.Where the value of expr is always assigned to a local variable named varname. varname ist eine Variable desselben Typs wie der Kompilierzeittyp expr.varname is a variable of the same type as the compile-time type of expr.

Wenn expr zu null ausgewertet wird, ergibt der is-Ausdruck true und weist null zu varname zu.If expr evaluates to null, the is expression produces true and assigns null to varname. Das var-Muster ist eine der wenigen Verwendungen von is, die true für einen null-Wert erzeugt.The var pattern is one of the few uses of is that produces true for a null value.

Sie können das var-Muster verwenden, um eine temporäre Variable innerhalb eines booleschen Ausdrucks zu erstellen, wie das folgende Beispiel zeigt:You can use the var pattern to create a temporary variable within a Boolean expression, as the following example shows:

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main()
    {
        int[] testSet = { 100271, 234335, 342439, 999683 };

        var primes = testSet.Where(n => Factor(n).ToList() is var factors
                                    && factors.Count == 2
                                    && factors.Contains(1)
                                    && factors.Contains(n));

        foreach (int prime in primes)
        {
            Console.WriteLine($"Found prime: {prime}");
        }
    }

    static IEnumerable<int> Factor(int number)
    {
        int max = (int)Math.Sqrt(number);
        for (int i = 1; i <= max; i++)
        {
            if (number % i == 0)
            {
                yield return i;
                if (i != number / i)
                {
                    yield return number / i;
                }
            }
        }
    }
}
// The example displays the following output:
//       Found prime: 100271
//       Found prime: 999683

Im vorhergehenden Beispiel wird die temporäre Variable verwendet, um das Ergebnis einer aufwendigen Operation zu speichern.In the preceding example, the temporary variable is used to store the result of an expensive operation. Die Variable kann dann mehrfach verwendet werden.The variable can then be used multiple times.

C#-SprachspezifikationC# language specification

Weitere Informationen finden Sie im Abschnitt is-Operator der C#-Sprachspezifikation sowie in den folgenden Vorschlägen für C#:For more information, see The is operator section of the C# language specification and the following C# language proposals:

Weitere InformationenSee also