Condividi tramite


Operatori di test dei tipi ed espressioni di cast - is, as, typeofe cast

Questi operatori ed espressioni eseguono il controllo del tipo o la conversione dei tipi. L'is controlla se il tipo di runtime di un'espressione è compatibile con un determinato tipo. L'as converte in modo esplicito un'espressione in un determinato tipo se il tipo di runtime è compatibile con tale tipo. Le espressioni di cast eseguono una conversione esplicita in un tipo di destinazione. L'typeof ottiene l'istanza System.Type per un tipo.

Il riferimento al linguaggio C# documenta la versione rilasciata più di recente del linguaggio C#. Contiene anche la documentazione iniziale per le funzionalità nelle versioni di anteprima pubblica per la prossima versione del linguaggio di programmazione.

La documentazione identifica tutte le funzionalità introdotte nelle ultime tre versioni della lingua o nelle anteprime pubbliche correnti.

Suggerimento

Per trovare quando una funzionalità è stata introdotta per la prima volta in C#, vedere l'articolo sulla cronologia delle versioni del linguaggio C#.

Operatore is

L' operatore is controlla se il tipo di runtime del risultato di un'espressione è compatibile con un determinato tipo. L'operatore is verifica anche un risultato dell'espressione rispetto a un criterio.

L'espressione con l'operatore di test del tipo is ha il formato seguente:

E is T

Dove E è un'espressione che restituisce un valore e T è il nome di un tipo o di un parametro di tipo. E non può essere un metodo anonimo o un'espressione lambda.

L'operatore is restituisce true quando un risultato di un'espressione è non null e le condizioni seguenti sono vere:

  • Il tipo di runtime di un risultato di un'espressione ha una conversione di identità in T.

  • Il tipo di runtime di un risultato di un'espressione deriva dal tipo T, implementa l'interfaccia T o esiste un'altra conversione di riferimento implicita da essa a T. Questa condizione riguarda le relazioni di ereditarietà e le implementazioni dell'interfaccia.

  • Il tipo di runtime di un risultato di un'espressione è un tipo valore nullable con il tipo sottostante T e Nullable<T>.HasValue è true.

  • Esiste una conversione di boxing o unboxing dal tipo di runtime del risultato di un'espressione al tipo T quando l'espressione non è un'istanza di ref struct.

L'operatore is non considera le conversioni definite dall'utente o le conversioni implicite dell'intervallo.

L'esempio seguente dimostra che l'operatore is restituisce true se il tipo di runtime del risultato di un'espressione deriva da un determinato tipo, ovvero se esiste una conversione di riferimento tra i tipi:

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
    }
}

L'esempio successivo mostra che l'operatore is prende in considerazione le conversioni boxing e unboxing ma non le conversioni numeriche:

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

Per informazioni sulle conversioni C#, vedere il capito Conversioni della specifica del linguaggio C#.

Test del tipo con criteri di ricerca

L'operatore is verifica anche un risultato dell'espressione rispetto a un criterio. Nell'esempio seguente viene illustrato come usare un modello di dichiarazione per controllare il tipo di runtime di un'espressione:

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

Per informazioni sui modelli supportati, vedere Modelli.

Operatore as

Usare l'operatore as per convertire in modo esplicito il risultato di un'espressione in un determinato tipo di valore di riferimento o nullable. Se la conversione non è possibile, l'operatore as restituisce null. A differenza di un'espressione cast, l'operatore non genera mai un'eccezione as.

Un'espressione nel formato

E as T

Dove E è un'espressione che restituisce un valore e T è il nome di un tipo o di un parametro di tipo, produce lo stesso risultato di

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

Ad eccezione del fatto che E viene valutato una sola volta.

L'operatore as considera solo conversioni di riferimenti, nullable, boxing e unboxing. Non è possibile usare l'operatore as per eseguire una conversione definita dall'utente. Per eseguire una conversione definita dall'utente, usare un'espressione cast.

Nell'esempio seguente viene illustrato l'uso dell'operatore as:

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
}

Nota

Come illustrato nell'esempio precedente, è necessario confrontare il risultato dell'espressione as con null per verificare se la conversione ha avuto esito positivo. È possibile usare l'operatoreis sia per verificare se la conversione ha esito positivo e, se ha esito positivo, assegnarne il risultato a una nuova variabile.

Espressione cast

Un'espressione cast del form (T)E converte in modo esplicito il risultato dell'espressione E nel tipo T. Se non esiste alcuna conversione esplicita dal tipo di E a tipo T, il compilatore genera un errore. In fase di esecuzione, è possibile che una conversione esplicita non riesca e che un'espressione cast generi un'eccezione.

L'esempio seguente illustra conversioni esplicite numeriche e di riferimento:

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

Per informazioni sulle conversioni esplicite supportate, vedere la sezione Conversioni esplicite della specifica del linguaggio C#. Per informazioni su come definire una conversione personalizzata del tipo esplicito o implicito, vedere Operatori di conversione definiti dall'utente.

Altri utilizzi di ()

È possibile usare le parentesi anche per chiamare un metodo oppure richiamare un delegato.

Un altro uso delle parentesi consiste nel regolare l'ordine in cui C# valuta le operazioni in un'espressione. Per altre informazioni, vedere Operatori C#.

Operatore typeof

L'operatore typeof ottiene l'istanza System.Type di un tipo. L'argomento dell'operatore typeof deve essere il nome o il parametro di un tipo, come illustrato nell'esempio seguente:

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]

L'argomento non può essere un tipo che richiede annotazioni di metadati. Esempi di questi tipi includono i tipi seguenti:

  • dynamic
  • string? (o qualsiasi tipo riferimento nullable)

Questi tipi non sono rappresentati direttamente nei metadati. I tipi includono attributi che descrivono il tipo sottostante. In entrambi i casi, è possibile usare il tipo sottostante. Usare dynamic anziché object. Usare string? anziché string.

È possibile usare l'operatore typeof anche con tipi generici non associati. Il nome di un tipo generico non associato deve contenere il numero appropriato di virgole, ovvero una in meno rispetto al numero di parametri del tipo. L'esempio seguente illustra l'uso dell'operatore typeof con un tipo generico non associato:

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

Un'espressione non può essere un argomento dell'operatore typeof. Per ottenere l'istanza System.Type per il tipo di runtime del risultato dell'espressione, usare il metodo Object.GetType.

Test del tipo con l'operatore typeof

Usare l'operatore typeof per controllare se il tipo di runtime del risultato dell'espressione corrisponde esattamente a un determinato tipo. L'esempio seguente illustra la differenza tra il controllo dei tipi eseguito usando l'operatore typeof e l'operatoreis :

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
    }
}

Overload degli operatori

Non è possibile eseguire l'overload degli isoperatori , ase typeof .

Un tipo definito dall'utente non può eseguire l'overload dell'operatore () , ma può definire conversioni di tipi personalizzate eseguite da un'espressione cast. Per altre informazioni, vedere Operatori di conversione definiti dall'utente.

Specifiche del linguaggio C#

Per altre informazioni, vedere le sezioni seguenti delle specifiche del linguaggio C#:

Vedi anche