Procedura: eseguire il cast sicuro tramite gli operatori as e is (Guida per programmatori C#)

Poiché gli oggetti sono polimorfici, per una variabile di un tipo di classe di base è possibile contenere un tipo derivato. Per accedere al metodo del tipo derivato, è necessario eseguire nuovamente il cast del valore nel tipo derivato. Tuttavia, tentare un cast semplice in questi casi crea il rischio della generazione di InvalidCastException. Per questo motivo C# fornisce gli operatori is e as. È possibile utilizzare questi operatori per verificare se un cast riuscirà senza provocare la generazione di un'eccezione. In generale, l'operatore as è più efficiente perché, se è possibile effettuare il cast, ne restituisce il valore. L'operatore is restituisce solo un valore booleano. Si può pertanto utilizzare quando si desidera solo determinare il tipo di un oggetto ma non si deve realmente eseguirne il cast.

Esempio

Negli esempi seguenti viene mostrato come utilizzare gli operatori is e as per eseguire il cast da un tipo riferimento a un altro senza il rischio della generazione di un'eccezione. Nell'esempio viene mostrato anche come utilizzare l'operatore as con i tipi valore nullable.

class SafeCasting
{
    class Animal
    {
        public void Eat() { Console.WriteLine("Eating."); }
        public override string ToString()
        {
            return "I am an animal.";
        }
    }
    class Mammal : Animal { }
    class Giraffe : Mammal { }

    class SuperNova { }

    static void Main()
    {
        SafeCasting app = new SafeCasting();

        // Use the is operator to verify the type.
        // before performing a cast.
        Giraffe g = new Giraffe();
        app.UseIsOperator(g);

        // Use the as operator and test for null
        // before referencing the variable.
        app.UseAsOperator(g);

        // Use the as operator to test
        // an incompatible type.
        SuperNova sn = new SuperNova();
        app.UseAsOperator(sn);

        // Use the as operator with a value type.
        // Note the implicit conversion to int? in 
        // the method body.
        int i = 5;
        app.UseAsWithNullable(i);


        double d = 9.78654;
        app.UseAsWithNullable(d);

        // Keep the console window open in debug mode.
        System.Console.WriteLine("Press any key to exit.");
        System.Console.ReadKey();
    }

    void UseIsOperator(Animal a)
    {
        if (a is Mammal)
        {
            Mammal m = (Mammal)a;
            m.Eat();
        }
    }

    void UseAsOperator(object o)
    {
        Mammal m = o as Mammal;
        if (m != null)
        {
            Console.WriteLine(m.ToString());
        }
        else
        {
            Console.WriteLine("{0} is not a Mammal", o.GetType().Name);
        }
    }

    void UseAsWithNullable(System.ValueType val)
    {
        int? j = val as int?;
        if (j != null)
        {
            Console.WriteLine(j);
        }
        else
        {
            Console.WriteLine("Could not convert " + val.ToString());
        }
    }
}

Vedere anche

Riferimenti

Tipi (Guida per programmatori C#)

Cast e conversioni di tipi (Guida per programmatori C#)

Tipi nullable (Guida per programmatori C#)