Boxing and Unboxing (as and is operator) in C#
July 31, 2019
Value types are the ones stored in the stack memory like the int, bool, float, double etc.
Reference types are the ones stored in heap memory with their reference stored in the stack memory like objects.
There are cases when we need to cast value types to reference types & vice versa. A similar case could be saving some integer data in a list of objects.
In this case, we need to cast integer (value type) to object (reference type).
Boxing
This concept is called as boxing i.e. converting a value type to a reference type to be used as a reference type.
Consider a scenario we are having a
List<object>
& we have an integer value. We want to save that integer value in the list of objects. To do so, we will save the integer value type as an object that we can add to the list.Since the object is the base class for all types, we can box the integer to object. For boxing to be done, the types need to be in the same hierarchy.
int value = 5;Object obj = (object)value; //boxing - casting the integer to object type
Now, we can add this variable obj to the list.
So what happened here?
The integer named value was stored originally in the stack memory. When we execute the next statement, a new object was created in the heap memory with its reference kept in the stack memory by the variable named obj.
It created a reference type for a value type.
A new copy of integer was copied to the object obj
int value = 5;
Object obj = value;
value = 6;
Console.WriteLine(obj);
Printing the value of obj even after changing the original value printed the output as 5.
Unboxing
When getting back the object from the list as object type, to assign it to an integer type, we need to unbox the parent type to a more specific type.
To assign an
object
to an integer
type, we need to cast it to int
type. This casting is called unboxing.
To unbox the object to an integer type, we write the following statement:
int unboxedValue = (int)obj;
Here, we cast the object to
int
type to store its value in the unboxedValue
variable.
In this statement, it uses the object obj to get its value from the heap & we store its value in the value type variable
unboxedVariable
.We can unbox the value to integer type only as it was originally the integer type that was boxed into the object type. We will get an invalid cast exception if we unbox it to some other type.
While unboxing it to some other type, we get an invalid cast exception.
See the image below showing the exception, when trying to cast the object obj to float type:
as/is operator
To prevent this invalid cast exception, we use the as or is operator.
The is operator
The
is
operator returns a boolean value. It checks if an object can be cast to another type & returns a boolean value. It returns the boolean value after trying the casting operation. If the casting is successful, it returns true else it returns false.int unboxedValue;
if (obj is int)
{
unboxedValue = (int)obj;
}
The as operator
The
as
operator returns the casted value if the value can be casted to a specific type, else it returns null.
var unboxedValue = obj as int;
If
obj
can be casted to int
, it will assign the integer value to variable unboxedVariable
, else it will assign a null value to the unboxedValue
.int? unboxedvalue = obj as int?;
Which one to use?
The
as
operator is preferred to use over is
operator. The as
operator involved only one casting operation to get the unboxed value whereas using the is
operator castes the value twice, once to check if it can be cast, second to actually cast the object.
0 comments