Webinar: C++ semantics - 06.11
One of the basic and most common operations with types is their check at runtime. In different cases — to get information about the type and to check the type — we should use different methods and operators. Below is their brief overview.
The typeof operator returns the System.Type instance. The instance corresponds to the type, the name of which is specified in the argument.
Type typeOfInt = typeof(int);
// [System.Int32]
Type typeOfString = typeof(string);
// [System.String]
Note that in the case of generic types, the typeof operator can accept both arguments of a constructed and an unbound type.
var typeOfGenericList = typeof(List<>);
// [System.Collections.Generic.List`1[T]]
var typeOfListOfStrings = typeof(List<String>);
// [System.Collections.Generic.List`1[System.String]]
GetType is an instance method of the Object class. This method can obtain the actual type of an object at the application runtime.
Object obj = new Object();
Object str = String.Empty;
Type type1 = obj.GetType();
// [System.Object]
Type type2 = str.GetType();
// [System.String]
At runtime, the is operator checks whether the expression type is compatible with the type specified in the operand.
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
This example shows that the is operator doesn't check the exact match. Instead, the operator checks the compatibility, meaning that the actual object type is specified or derived from it.
The is operator also has a variety of other features. They are listed below.
Check for null
After we check the actual type, we also check the value for the null inequation.
Object obj = null;
Console.WriteLine(obj is Object); // False, since obj is null
The boxed type check
We can check the boxed value actual type with the is operator.
Object obj = 42; // boxing
Console.WriteLine(obj is int); // True
Console.WriteLine(obj is double); // False
The Nullable<T> underlying type check
The is operator allows you to check whether a value exists in the Nullable<T> instance (Nullable<T>.HasValue) and its type.
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
To select an operator/method for working with types, you can use the following approach:
The example below clearly demonstrates the difference between type checking via the GetType method and via the is operator.
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
}
The actual type of the object referenced by obj is C. Therefore, the GetType method for obj returns an instance of System.Type corresponding to C. The result of the typeof(B) operator is an instance describing type B. Comparing objects describing different types, as expected, results in false.
The is operator checks for compatibility, not exact match. Since the compatibility of an object of type C with B is checked, the result will be true.
0