Run-time type information. Statements is, as. Examples
Contents
- 1. What is the run-time type information (RTTI)? Advantages of using
- 2. What keywords (operators) are introduced in C# to provide runtime type identification?
- 3. The general form of operator is
- 4. Examples of using operator is for basic types and expressions
- 5. How does the is operator work when classes are inherited? Examples
- 6. Operator as. General form
- 7. An example of using the as operator
- 8. How can the as operator be replaced by the is operator? Example
- Related topics
Search other websites:
1. What is the run-time type information (RTTI)? Advantages of using
In some cases, when writing programs, you need to determine the type of data during program execution. This means that at the time of compilation it is not known what type this or that data will have. To define a type in C#, an appropriate mechanism has been developed, which is called run-time (dynamic) type identification.
Runtime type identification is effective in the following cases:
- if the classes inherit each other or form a hierarchy, then if there is a reference to the base class, you can determine the type of the object by this reference (see item 5);
- if it is necessary to determine the result of a casting operation in order to avoid generating an exceptional situation in case of an erroneous casting;
- runtime type identification is effectively used in reflection. More details about reflection is described here.
⇑
2. What keywords (operators) are introduced in C# to provide runtime type identification?
To provide dynamic identification of types in the C# language, three operators are introduced:
- operator is – checks if the type of the expression matches the specified data type;
- operator as – designed to avoid the occurrence of an exceptional situation in case of unsuccessful type conversion;
- оператор typeof – used to obtain information about a given type (class). More on the typeof operator is described here.
⇑
3. The general form of operator is
The general form of the is operator is as follows:
expression is type
here
- expression have the designation of an expression that describes an object;
- type is a type with which the type of expression is compared. If the expression and type have the same data type, then the result of the operation will be true. Otherwise, the result of the is operation will be false.
Most often, the is operator is used in the condition of the if statement. In this case, the general form of the if statement with the is operator is as follows
if (expression is type) { // operations that need to be performed if the types match // ... } else { // operations that need to be performed if the types do not match // ... }
⇑
4. Examples of using the is operator for basic types and expressions
Example 1. A snippet of code demonstrating the use of the is operator for variables of basic types int, float.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApp5 { class Program { static void Main(string[] args) { // runtime type information int a, b; float x; // variables must be initialized before use a = 25; b = 33; x = 3.9f; // check if there is 'a' of type int if (a is int) Console.WriteLine("Variable a is of type int."); else Console.WriteLine("Variable a is not of type int"); // check if there is a variable b of type float if (b is float) Console.WriteLine("Variable b is of type float"); else Console.WriteLine("Variable b is not of type float"); // check if there is a variable x of type double if (x is double) Console.WriteLine("Variable x is of type double"); else Console.WriteLine("Variable x is not of type double"); } } }
As can be seen from the above example, in order to use the is operator, the expression may have some value. If at the beginning of the Main() function, remove the assignment lines of the variables a, b, x
... a = 25; b = 33; x = 3.9f; ...
the compiler will generate an error like
Use of unassigned local variable a Use of unassigned local variable b Use of unassigned local variable x
Example 2. The code snippet shows how to use the is operator to determine the type of a calculated expression.
// dynamic type identification // definition of expression type float x; // variables must be initialized before use x = 3.9f; // check if the expression of type double if ((2.5 + x) is double) Console.WriteLine("The expression is of type double"); else Console.WriteLine("The expression does not have type double "); // Result - "The expression is of type double" // Determining the type of expression 2 * 2 if ((2 * 2) is int) Console.WriteLine("Type int"); else if ((2 * 2) is uint) Console.WriteLine("Type uint"); else if ((2 * 2) is long) Console.WriteLine("Type long"); else if ((2 * 2) is byte) Console.WriteLine("Тип byte"); // Result - "Type int"
⇑
5. How does the is operator work when classes are inherited? Examples
The advantages of using dynamic type identification are particularly apparent in the case of class inheritance. If there is a reference to the base class, then this link can be used to determine the type of object in the inheritance hierarchy.
Example 1. Let 2 classes be given which form a hierarchy. BaseClass is base class. The DerivedClass class is derived from the BaseClass class. With the help of the is operator, the class object is determined to belong to a given type and the object is compatible with a given type.
// base class class BaseClass { public int d; } // derived class from the base class class DerivedClass : BaseClass { public int dd; }
The following demonstrates the use of objects of the base and derived classes in conjunction with the is operator
// creating objects of BaseClass and DerivedClass classes BaseClass bc = new BaseClass(); DerivedClass dc = new DerivedClass(); // the use of objects bc and dc if (bc is BaseClass) Console.WriteLine("Object bc is of type BaseClass"); if (bc is DerivedClass) Console.WriteLine("Object bc is compatible with DerivedClass"); if (dc is BaseClass) Console.WriteLine("Object dc is compatible with BaseClass"); if (dc is DerivedClass) Console.WriteLine("Object dc is of type DerivedClass");
As a result of the above code, the following will be displayed
Object bc is of type BaseClass Object dc is compatible with BaseClass Object dc is of type DerivedClass
In the line
... if (bc is DerivedClass) Console.WriteLine("Object bc is compatible with DerivedClass"); ...
the condition value in the if statement is false, since the base class object cannot be compatible with the derived class. However, on the contrary, the derived class object is compatible with the base class, since the derived class extends the capabilities of the base class.
Example 2. There are 3 classes with the names A, B, C that form a hierarchy: class A is basic, class B inherits class A, class C inherits class B. The declaration of classes has the following form:
// base class class A { public int a; } // class B inherits A class B : A { public int b; } // class C inherits B class C : B { public int c; }
Below is an example that determines the type of an object of class B and its compatibility with types A, C.
// the object of class B B objB = new B(); if (objB is A) Console.WriteLine("objB is compatible with type A "); if (objB is B) Console.WriteLine("objB is of type B"); if (objB is C) Console.WriteLine("obJB is compatible with type C");
As a result of executing the above code, a message will be displayed on the screen:
objB is compatible with type A objB is of type B
⇑
6. Operator as. General form
The as operator is used in tasks in which type casting operations are performed. If the type conversion is unsuccessful, an exception is generated. The as operator is intended to prevent the occurrence of an exceptional situation in the case of a failed type conversion.
The general form of the as operator is:
expression as type
here expression is a separate expression that is cast to type. If the expression is typed to the type correctly, then the result of the as operation is a type reference. Otherwise, the result of the as operation is null reference.
In view of the above, the general form of the as operator, which is located on the right-hand side of the assignment operator, is:
objName = expression as type;
here objName – the name of the object that will contain the result. The result may be null or a reference to an object of class type.
⇑
7. An example of using the as operator
In the example, the as operator is used for the preceding check for the correctness of the type cast without raising an exception.
Let classes A, B, C be declared which form a hierarchy
// base class class A { public int a; } // class B inherits A class B : A { public int b; } // class C inherits B class C: B { public int c; }
The following demonstrates the use of the as operator for classes A, B, C
// objects of classes A, B, C A objA = new A(); B objB = new B(); C objC = new C(); // try to perform a cast, if possible // the result of casting the objA object is entered into objB objB = objA as B; if (objB == null) Console.WriteLine("It is impossible to convert ObjA to the type B "); else Console.WriteLine("It is possible to convert objA to type B "); // another attempt to convert objC to type B, the result in objB objB = objC as B; // output of the result if (objB == null) Console.WriteLine("It is impossible to convert objC to the type B "); else Console.WriteLine("It is possible to convert objC to type B ");
As a result of executing the above code, the screen will be displayed
It is impossible to convert objA to type B It is possible to convert objC to type B
⇑
8. How can the as operator be replaced by the is operator? Example
In this example, the as operator is replaced with the is operator. First, a check is performed on the admissibility of type casting, and only then the cast occurs. Let three classes A, B, C be given which have such declaration
// base class class A { public int a; } // class B inherits A class B : A { public int b; } // class C inherits B class C : B { public int c; }
Below is a code snippet that uses the is operator to determine the validity of a cast. There is a check using the if statement
// objects A, B, C of classes A objA = new A(); B objB = new B(); C objC = new C(); // attempt to cast objA, objC to type B using the is operator if (objA is B) objB = (B)objA; else objB = null; if (objB == null) Console.WriteLine("It is impossible to convert objA to the type B"); else Console.WriteLine("It is possible to convert objA to the type B"); // checking objC in the same way if (objC is B) objB = (B)objC; else objB = null; if (objB == null) Console.WriteLine("It is impossible to convert objC to the type B"); else Console.WriteLine("It is possible to convert objC to the type B");
As a result of executing the above code, the following result will be displayed
It is impossible to convert objA to the type B It is possible to convert objC to the type B
⇑
Related topics
- Reflection of types. Getting type metadata. The System.Reflection namespace. Class System.Type. Ways to get information about types. Operator typeof
- Examples of obtaining information about methods, interfaces, classes, structures, enumerations, delegates, type fields, method parameters, type statistics
- Dynamically loadable assemblies. Class Assembly. Methods Load() and LoadFrom()
- Late binding. Method call. Example. Class System.Activator. Method Invoke()