is (Riferimenti per C#)is (C# Reference)

Controlla se un oggetto è compatibile con un determinato tipo o (a partire da C# 7.0) controlla un'espressione rispetto a un criterio.Checks if an object is compatible with a given type, or (starting with C# 7.0) tests an expression against a pattern.

Verifica della compatibilità del tipoTesting for type compatibility

La parola chiave is valuta la compatibilità dei tipi in fase di esecuzione.The is keyword evaluates type compatibility at runtime. Determina se un'istanza dell'oggetto o il risultato di un'espressione può essere convertito in un tipo specificato.It determines whether an object instance or the result of an expression can be converted to a specified type. Presenta la sintassiIt has the syntax

   expr is type

dove expr è un'espressione che restituisce un'istanza di un tipo e type è il nome del tipo in cui il risultato di expr deve essere convertito.where expr is an expression that evaluates to an instance of some type, and type is the name of the type to which the result of expr is to be converted. L'istruzione is è true se expr è non Null e l'oggetto risultante dalla valutazione dell'espressione può essere convertito in type; in caso contrario, restituisce false.The is statement is true if expr is non-null and the object that results from evaluating the expression can be converted to type; otherwise, it returns false.

Ad esempio, il codice seguente determina se obj può essere convertito in un'istanza di tipo Person:For example, the following code determines if obj can be cast to an instance of the Person type:

if (obj is Person) {
   // Do something if obj is a Person.
}

L'istruzione is è true se:The is statement is true if:

  • expr è un'istanza dello stesso tipo di type.expr is an instance of the same type as type.

  • expr è un'istanza di un tipo che deriva da type.expr is an instance of a type that derives from type. In altre parole, il risultato di expr può subire l'upcast a un'istanza di type.In other words, the result of expr can be upcast to an instance of type.

  • expr ha un tipo in fase di compilazione che è una classe di base di type e expr ha un tipo di runtime che è type o è derivato da type.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. Il tipo in fase di compilazione di una variabile è il tipo della variabile come definito nella relativa dichiarazione.The compile-time type of a variable is the variable's type as defined in its declaration. Il tipo di runtime di una variabile è il tipo dell'istanza che viene assegnato alla variabile.The runtime type of a variable is the type of the instance that is assigned to that variable.

  • expr è un'istanza di un tipo che implementa l'interfaccia type.expr is an instance of a type that implements the type interface.

Nell'esempio seguente viene illustrato che l'espressione is restituisce true per ognuna di queste conversioni.The following example shows that the is expression evaluates to true for each of these conversions.

using System;

public class Class1 : IFormatProvider
{
   public object GetFormat(Type t)
   {
      if (t.Equals(this.GetType()))      
         return this;
      return null;
   }
}

public class Class2 : Class1
{
   public int Value { get; set; }
}

public class Example
{
   public static void Main()
   {
      var cl1 = new Class1();
      Console.WriteLine(cl1 is IFormatProvider);
      Console.WriteLine(cl1 is Object);
      Console.WriteLine(cl1 is Class1);
      Console.WriteLine(cl1 is Class2); 
      Console.WriteLine();
 
      var cl2 = new Class2();
      Console.WriteLine(cl2 is IFormatProvider);
      Console.WriteLine(cl2 is Class2);
      Console.WriteLine(cl2 is Class1);
      Console.WriteLine();
      
      Class1 cl = cl2;
      Console.WriteLine(cl is Class1);
      Console.WriteLine(cl is Class2);
   }
}
// The example displays the following output:
//     True
//     True
//     True
//     False
//     
//     True
//     True
//     True
//     
//     True
//     True

La parola chiave is genera un avviso in fase di compilazione se è noto che l'espressione sarà sempre true o false.The is keyword generates a compile-time warning if the expression is known to always be either true or false. Considera solo le conversioni dei riferimenti, le conversioni boxing e unboxing; non considera le conversioni definite dall'utente o le conversioni definite dagli operatori implicit ed explicit di un tipo.It only considers reference conversions, boxing conversions, and unboxing conversions; it does not consider user-defined conversions or conversions defined by a type's implicit and explicit operators. Nell'esempio seguente vengono generati gli avvisi, poiché il risultato della conversione è noto in fase di compilazione.The following example generates warnings because the result of the conversion is known at compile time. L'espressione is per le conversioni da int a long e double restituisce false, poiché queste conversioni vengono gestite dall'operatore implicit.The is expression for conversions from int to long and double return false, since these conversions are handled by the implicit operator.

Console.WriteLine(3 is int);
Console.WriteLine();

int value = 6;
Console.WriteLine(value is long);
Console.WriteLine(value is double);
Console.WriteLine(value is object);
Console.WriteLine(value is ValueType);
Console.WriteLine(value is int);
// Compilation generates the following compiler warnings:
//   is2.cs(8,25): warning CS0183: The given expression is always of the provided ('int') type
//   is2.cs(12,25): warning CS0184: The given expression is never of the provided ('long') type
//   is2.cs(13,25): warning CS0184: The given expression is never of the provided ('double') type
//   is2.cs(14,25): warning CS0183: The given expression is always of the provided ('object') type
//   is2.cs(15,25): warning CS0183: The given expression is always of the provided ('ValueType') type
//   is2.cs(16,25): warning CS0183: The given expression is always of the provided ('int') type

expr non può essere un metodo anonimo o un'espressione lambda.expr cannot be an anonymous method or lambda expression. Può essere una qualsiasi altra espressione che restituisce un valore.It can be any other expression that returns a value. Nell'esempio seguente viene usato is per valutare il valore restituito di una chiamata al metodo.The following example uses is to evaluate the return value of a method call.

using System;

public class Example
{
   public static void Main()
   {
      double number1 = 12.63; 
      if (Math.Ceiling(number1) is double)
         Console.WriteLine("The expression returns a double.");
      else if (Math.Ceiling(number1) is decimal)    
         Console.WriteLine("The expression returns a decimal.");

      decimal number2 = 12.63m; 
      if (Math.Ceiling(number2) is double)
         Console.WriteLine("The expression returns a double.");
      else if (Math.Ceiling(number2) is decimal)    
         Console.WriteLine("The expression returns a decimal.");

   }
}
// The example displays the following output:
//     The expression returns a double.
//     The expression returns a decimal.

A partire da C# 7.0, è possibile usare criteri di ricerca con il criterio del tipo per scrivere codice più conciso che usa l'istruzione is.Starting with C# 7.0, you can use pattern matching with the type pattern to write more concise code that uses the is statement.

Criteri di ricerca con isPattern matching with is

A partire da C# 7.0, le istruzioni is e switch supportano i criteri di ricerca.Starting with C# 7.0, the is and switch statements support pattern matching. La parola chiave is supporta i criteri seguenti:The is keyword supports the following patterns:

  • Criterio del tipo, che verifica se un'espressione può essere convertita in un tipo specificato e, in tal caso, esegue il cast a una variabile di quel tipo.Type pattern, which tests whether an expression can be converted to a specified type and, if it can be, casts it to a variable of that type.

  • Criterio costante, che verifica se un'espressione restituisce un valore costante specificato.Constant pattern, which tests whether an expression evaluates to a specified constant value.

  • Criterio var, una corrispondenza che ha sempre esito positivo e associa il valore di un'espressione a una nuova variabile locale.var pattern, a match that always succeeds and binds the value of an expression to a new local variable.

Criterio del tipoType pattern

Quando si usa il criterio del tipo per eseguire i criteri di ricerca, is verifica se un'espressione può essere convertita in un tipo specificato e, in tal caso, esegue il cast a una variabile di quel tipo.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. È una semplice estensione dell'istruzione is che consente la valutazione e la conversione concisa del tipo.It's a straightforward extension of the is statement that enables concise type evaluation and conversion. Il formato generale del criterio del tipo è is:The general form of the is type pattern is:

   expr is type varname 

dove expr è un'espressione che restituisce un'istanza di un tipo, type è il nome del tipo in cui il risultato di expr deve essere convertito e varname è l'oggetto in cui il risultato di exprdeve essere convertito se il test is è true.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.

L'espressione is è true se expr non è null e una delle condizioni seguenti è true:The is expression is true if expr isn't null, and any of the following is true:

  • expr è un'istanza dello stesso tipo di type.expr is an instance of the same type as type.

  • expr è un'istanza di un tipo che deriva da type.expr is an instance of a type that derives from type. In altre parole, il risultato di expr può subire l'upcast a un'istanza di type.In other words, the result of expr can be upcast to an instance of type.

  • expr ha un tipo in fase di compilazione che è una classe di base di type e expr ha un tipo di runtime che è type o è derivato da type.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. Il tipo in fase di compilazione di una variabile è il tipo della variabile come definito nella relativa dichiarazione.The compile-time type of a variable is the variable's type as defined in its declaration. Il tipo di runtime di una variabile è il tipo dell'istanza che viene assegnato alla variabile.The runtime type of a variable is the type of the instance that is assigned to that variable.

  • expr è un'istanza di un tipo che implementa l'interfaccia type.expr is an instance of a type that implements the type interface.

A partire da C# 7.1, expr può avere un tipo in fase di compilazione definito da un parametro di tipo generico e dai relativi vincoli.Beginning with C# 7.1, expr may have a compile-time type defined by a generic type parameter and its constraints.

Se expr è true e is viene usato con un'istruzione if, varname viene assegnato solo all'interno dell'istruzione if.If expr is true and is is used with an if statement, varname is assigned within the if statement only. L'ambito di varname va dall'espressione is alla fine del blocco che racchiude l'istruzione if.The scope of varname is from the is expression to the end of the block enclosing the if statement. Se si usa varname in qualsiasi altra posizione, viene generato un errore in fase di compilazione perché è stata usata una variabile che non è stata assegnata.Using varname in any other location generates a compile-time error for use of a variable that has not been assigned.

Nell'esempio seguente viene usato il criterio del tipo is per specificare l'implementazione di un metodo IComparable.CompareTo(Object) del tipo.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.");
    }
}

Senza criteri di ricerca, questo codice potrebbe essere scritto come segue.Without pattern matching, this code might be written as follows. L'uso di criteri di ricerca del tipo produce codice più compatto e leggibile eliminando la necessità di verificare se il risultato di una conversione è un null.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);
    }
}

Anche il criterio del tipo is produce codice più compatto quando determina il tipo di un tipo di valore.The is type pattern also produces more compact code when determining the type of a value type. Nell'esempio seguente viene usato il criterio del tipo is per determinare se un oggetto è un'istanza Person o Dog prima di visualizzare il valore di una proprietà appropriata.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

Il codice equivalente senza criteri di ricerca richiede un'assegnazione separata che include un cast esplicito.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

Criterio costante Constant pattern

Quando si eseguono criteri di ricerca con il criterio costante, is verifica se un'espressione è uguale a una costante specificata.When performing pattern matching with the constant pattern, is tests whether an expression equals a specified constant. In C# 6 e versioni precedenti, il criterio costante è supportato per l'istruzione switch.In C# 6 and earlier versions, the constant pattern is supported by the switch statement. A partire da C# 7.0 è supportato anche dall'istruzione is.Starting with C# 7.0, it's supported by the is statement as well. La sintassi è la seguente:Its syntax is:

   expr is constant

dove expr è l'espressione da valutare e constant è il valore da testare.where expr is the expression to evaluate, and constant is the value to test for. constant può essere una delle espressioni costanti seguenti:constant can be any of the following constant expressions:

  • Un valore letterale.A literal value.

  • Il nome di una variabile const dichiarata.The name of a declared const variable.

  • Una costante di enumerazione.An enumeration constant.

L'espressione costante viene valutata nel modo seguente:The constant expression is evaluated as follows:

  • Se expr e constant sono tipi integrali, l'operatore di uguaglianza C# determina se l'espressione restituisce true (ovvero, se expr == constant).If expr and constant are integral types, the C# equality operator determines whether the expression returns true (that is, whether expr == constant).

  • In caso contrario, il valore dell'espressione è determinato da una chiamata al metodo Object.Equals(expr, constant) statico.Otherwise, the value of the expression is determined by a call to the static Object.Equals(expr, constant) method.

Nell'esempio seguente vengono combinati i criteri di tipo e costante per verificare se un oggetto è un'istanza Dice e, in tal caso, per determinare se il valore di un tiro di dadi è 6.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!

Verifica che null possa essere eseguito usando il criterio costante.Checking for null can be performed using the constant pattern. La parola chiave null è supportata dall'istruzione is.The null keyword is supported by the is statement. La sintassi è la seguente:Its syntax is:

   expr is null

L'esempio seguente illustra un confronto di controlli null: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
}

Criterio var var pattern

Il criterio var è applicabile a qualsiasi tipo o valore.The var pattern is a catch-all for any type or value. Il valore di expr viene sempre assegnato a una variabile locale dello stesso tipo del tipo della fase di compilazione di expr.The value of expr is always assigned to a local variable the same type as the compile time type of expr. Il risultato dell'espressione is è sempre true.The result of the is expression is always true. La sintassi è la seguente:Its syntax is:

   expr is var varname

Nell'esempio seguente viene usato il criterio var per assegnare un'espressione a una variabile denominata obj.The following example uses the var pattern to assign an expression to a variable named obj. Viene quindi visualizzato il valore e il tipo di obj.It then displays the value and the type of obj.

using System;

class Program
{
    static void Main()
   {
      object[] items = { new Book("The Tempest"), new Person("John") };
      foreach (var item in items) {
        if (item is var obj)
          Console.WriteLine($"Type: {obj.GetType().Name}, Value: {obj}"); 
      }
   }
}

class Book
{
    public Book(string title) 
    {
       Title = title;    
    }

    public string Title { get; set; }

    public override string ToString()
    {
       return Title;
    }
}

class Person
{
   public Person(string name)
   {
      Name = name;
   }

   public string Name 
   { get; set; }

   public override string ToString()
   {
      return Name;
   }
}
// The example displays the following output:
//       Type: Book, Value: The Tempest
//       Type: Person, Value: John

Specifiche del linguaggio C#C# Language Specification

Per altre informazioni, vedere la specifica del linguaggio C#.For more information, see the C# Language Specification. La specifica del linguaggio costituisce il riferimento ufficiale principale per la sintassi e l'uso di C#.The language specification is the definitive source for C# syntax and usage.

Vedere ancheSee also