Динамическая идентификация типов (RTTI) позволяет определить тип объекта во время выполнения программы. Она оказывается полезной по целому ряду причин. В частности, по ссылке на базовый класс можно довольно точно определить тип объекта, доступного по этой ссылке. Динамическая идентификация типов позволяет также проверить заранее, насколько удачным будет исход приведения типов, предотвращая исключительную ситуацию в связи с неправильным приведением типов. Кроме того, динамическая идентификация типов является главной составляющей рефлексии.
Для поддержки динамической идентификации типов в C# предусмотрены три ключевых слова: is
, as
и typeof
. Каждое из этих ключевых слов рассматривается далее по очереди.
Конкретный тип объекта можно определить с помощью оператора is
. Ниже приведена его общая форма:
выражение is тип
где is
оба типа определяются как совместимые, если они одного и того же типа или если предусмотрено преобразование ссылок, упаковка или распаковка.
Ниже приведен пример применения оператора is.
// Продемонстрировать применение оператора is.
using System;
class A {}
class В : A {}
class UseIs {
static void Main() {
A a = new A();
В b = new В();
if (a is A)
Console.WriteLine("а имеет тип A");
if(b is A)
Console.WriteLine ("b совместим с А, поскольку он производный от А");
if(a is В)
Console.WriteLine("Не выводится, поскольку а не производный от В");
if(b is В)
Console.WriteLine("В имеет тип В");
if(a is object)
Console.WriteLine("а имеет тип object");
}
}
Вот к какому результату приводит выполнение этого кода.
а имеет тип А
b совместим с А, поскольку он производный от А
b имеет тип В
а имеет тип object
Большая часть выражений is
в приведенном выше примере не требует пояснений, но два из них необходимо все же разъяснить. Прежде всего, обратите внимание на следующую строку кода.
if (b is А)
Console.WriteLine("b совместим с А, поскольку он производный от А");
Условный оператор if
выполняется, поскольку b является объектом типа В, производным от типа А. Но обратное несправедливо. Так, если в строке кода
if(a is В)
Console.WriteLine("Не выводится, поскольку а не производный от В");
условный оператор if
не выполняется, поскольку а является объектом типа А, не производного от типа В. Поэтому а
Иногда преобразование типов требуется произвести во время выполнения, но не генерировать исключение, если исход этого преобразования окажется неудачным, что вполне возможно при приведении типов. Для этой цели служит оператор as
, имеющий следующую общую форму:
выражение as тип
где as
может использоваться только для преобразования ссылок, идентичности, упаковки, распаковки.
В некоторых случаях оператор as
может служить удобной альтернативой оператору is
. В качестве примера рассмотрим следующую программу, в которой оператор is используется для предотвращения неправильного приведения типов.
// Использовать оператор is для предотвращения неправильного приведения типов.
using System;
class A { }
class В : A { }
class CheckCast {
static void Main() {
A a = new A();
В b = new В();
// Проверить, можно ли привести а к типу В.
if (a is В) // если да, то выполнить приведение типов
b = (В)a;
else // если нет, то пропустить приведение типов
b = null;
if (b == null)