Практическое руководство. Безопасное приведение с помощью операторов as и is (Руководство по программированию на C#)

Поскольку объекты являются полиморфными, в переменной типа базового класса может храниться производный тип. Для доступа к методу производного типа необходимо выполнить приведение значения обратно в производный тип. Однако попытка выполнения простого приведения в этих случаях создает риск возникновения InvalidCastException. Вот почему в С# предоставлены операторы is и as. Эти операторы можно использовать, чтобы проверить, будет ли приведение успешным, не вызывая исключение. В общем оператор as более эффективен, поскольку он фактически возвращает значение приведения, если приведение может быть выполнено успешно. Оператор is возвращает только логическое значение. Поэтому его можно использовать, если необходимо определить тип объекта, но нет необходимости выполнить его фактическое приведение.

Пример

В следующем примере показано использование операторов is и as для выполнения приведения от одного ссылочного типа к другому, не вызывая исключение. Также в примере показано использование оператора as с нулевыми типами значений.

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());
        }
    }
}

См. также

Ссылки

Типы (Руководство по программированию на C#)

Приведение и преобразование типов (Руководство по программированию на C#)

Типы, допускающие значения NULL (Руководство по программированию на C#)