C#. Boxing and unboxing. The need (advantages) of using generics

Boxing and unboxing. The need (advantages) of using generics. Increase type safety by using generics


Contents


Search other resources:




1. Boxing and unboxing

As you know, in the .NET Framework all base types (int, double, char, etc.) are represented by the corresponding class or structure (Integer, Double, Char, etc.) in the general hierarchical structure of classes. At the top of this structure is the Object type, which can be accessed by the name object. This means that it is allowed to declare a variable of type Object and use it to work with any type as shown below.

...

// You can also work through the base Object class
Object a;
object b;
a = 25; // assigning a value of type int
b = "bestprog"; // assigning a value of type string
Console.WriteLine("a = {0}", a); // a = 25
Console.WriteLine("b = {0}", b); // b = bestprog

// The variable a is again assigned a value of a different double type
a = 2.88;
Console.WriteLine("a = {0}", a); // a = 2.88

...

It is also allowed to use a variable of type object on the right side of the assignment operator:

...

// The variable of type object
object c;
c = 'A'; // assigned a char value

char cc; // The variable of type char
cc = (char)c; // here you need an explicit casting of types, otherwise an error at the compilation stage
Console.WriteLine("cc = {0}", cc); // cc = A

...

But in this case, you need to specify an explicit type conversion, as can be seen from the line

...
cc = (char)c;
...

otherwise there will be a compile-time error.

If a variable of type object is used on the left side of an assignment operator, then the compiler performs the so-called boxing. If a variable or value of type object is used on the right side of an assignment statement, the compiler performs unboxing.

Thus, the following definitions can be given. Boxing is the process of saving a value of a base type (int, char, double …) in the instance of an object. Unboxing is the process of pulling a boxed value (int, double, char, …) from an object. The following example demonstrates the difference between these terms:

...

object a;

// int type is boxed into object type
a = 300; // boxing: object <= int

int b;
b = (int)a; // unboxing: int <= object

...

 

2. What’s the difference between using generics and casting to object? Demonstration of the benefits of using generics. Example

As mentioned in paragraph 1, in C# programs, you can declare references to the Object type by referring to the names object or Object. Due to inheritance, variables of type Object can be assigned the value of any inherited types (see p. 1).

Based on the above, we can conclude that using the Object type can replace generics. Then a reasonable question arises: why use generics if they can be completely replaced by the object type?

Using generics instead of using the object type has the following benefits:

  • no explicit type conversion in the assignment operator when using generics;
  • ensuring typical safety. An error of incorrect type conversion is generated already at the compilation stage and not at the program execution stage;
  • productivity increase. For the type object, the assignment operation takes longer, since the boxing, unboxing takes place.

These advantages are discussed in more detail in the following paragraphs.

 

2.1. Advantage 1. No explicit casting

If generalization is used, then there is no need to perform explicit typecasting in the assignment operation, as shown in Figure 1.

C#. Generics. Explicit casting type

Figure 1. The difference in explicit casting to int between generic and object

 

2.2. Advantage 2. Ensuring typical safety in generics

When using the object class as a type, you can make an error that will not be detected at compile time. This error will end up at runtime, which is unacceptable.

Figure 2 implements the same classes as in Figure 1. However, in the main() function, an attempt is made to set a double value for both classes.

In the case of ObjectClass, no compile-time error occurs. This error will throw a runtime exception.

In the case of GenClass<T>, the error will be detected at compile time. This is due to the fact that typed code is generated with a binding to the int type. In this code, errors are identified at compile time. This is the main benefit of generics, which improve type safety.

C#. Generics. Features of error detection by the compiler

Figure 2. Features of error detection by the compiler for a generic and non-generic classes

 

2.3. Advantage 3. Productivity increase

Using generic classes provides better performance than non-generic ones. When assigning a value of type object to other types and vice versa, the compiler performs boxing and unboxing (see p. 1). This process is more time consuming than using generics. In the case of generics, typed code is generated with binding to a specific type, which is faster.

Figure 3 reflects the declaration of two classes ObjectClass and GenClass. The main() function highlights the code snippets that show the performance difference between objects and generics.

C#. Generics. The difference in code execution performance between a generic class and a class of type object

Figure 3. The difference in code execution performance between a generic class and a class of type object. Assignment for generic classes is faster

 


Related topics