Одной из базовых и при том наиболее частых операций работы с типами является их проверка на этапе исполнения. Как для получения информации о типе, так и для его проверки, в разных случаях следует использовать различные методы и операторы. Ниже представлен их краткий обзор.
Оператор typeof возвращает экземпляр System.Type, соответствующий типу, имя которого указано в аргументе.
Type typeOfInt = typeof(int);
// [System.Int32]
Type typeOfString = typeof(string);
// [System.String]
Обратите внимание, что в случае с обобщёнными типами оператор typeof может принимать как аргументы сконструированного, так и неограниченного типа.
var typeOfGenericList = typeof(List<>);
// [System.Collections.Generic.List`1[T]]
var typeOfListOfStrings = typeof(List<String>);
// [System.Collections.Generic.List`1[System.String]]
GetType – экземплярный метод класса Object, который позволяет получить фактический тип объекта на этапе исполнения приложения.
Object obj = new Object();
Object str = String.Empty;
Type type1 = obj.GetType();
// [System.Object]
Type type2 = str.GetType();
// [System.String]
Оператор is позволяет на этапе исполнения проверить, совместим ли тип выражения с указанным в операнде типом.
Object obj = new Object();
Object str = String.Empty;
Console.WriteLine(obj is Object); // True
Console.WriteLine(obj is String); // False
Console.WriteLine(str is Object); // True
Console.WriteLine(str is String); // True
Как видно из этого примера, оператор is проверяет не точное соответствие, а совместимость – то есть то, что фактический тип объекта является указанным или производным от него.
Оператор is обладает и рядом других особенностей, перечисленных ниже.
Проверка на null
Кроме проверки фактического типа, также производится проверка значения на неравенство null.
Object obj = null;
Console.WriteLine(obj is Object); // False, так как obj - null
Проверка упакованного типа
С помощью оператора is можно проверить фактический тип упакованного значения.
Object obj = 42; // boxing
Console.WriteLine(obj is int); // True
Console.WriteLine(obj is double); // False
Проверка нижележащего типа Nullable<T>
Оператор is позволяет проверять, наличие значения в экземпляре Nullable<T> (Nullable<T>.HasValue) и его тип.
int? nullableInt1 = 62;
int? nullableInt2 = null;
Console.WriteLine(nullableInt1 is int?); // True
Console.WriteLine(nullableInt1 is int); // True
Console.WriteLine(nullableInt1 is double); // False
Console.WriteLine(nullableInt2 is int?); // False
Console.WriteLine(nullableInt2 is int); // False
Console.WriteLine(nullableInt2 is double); // False
Для выбора оператора / метода работы с типами можно использовать следующий подход:
Более наглядно разница между проверкой типа через метод GetType и оператор is демонстрируется в примере ниже.
class A { .... }
class B : A { .... }
class C : B { .... }
void Foo()
{
A obj = new C();
Console.WriteLine(obj.GetType() == typeof(B)); // False
Console.WriteLine(obj is B); // True
}
Фактический тип объекта, на который ссылается obj, – C. Следовательно, метод GetType для obj возвращает экземпляр System.Type, соответствующий C. Результат работы оператора typeof(B) - экземпляр, описывающий тип B. Сравнение объектов, описывающих разные типы, ожидаемо даёт false.
Оператор is проверяет совместимость, а не точное соответствие. Так как проверяется совместимость объекта типа C с B, результатом будет true.
0