Boxing and unboxing are particularly useful in cases where we would like to use the ThreadPool class provided by .Net.
ThreadPool.QueueUserWorkItem() method allows us to queue up a method for execution on a thread pool thread. The method to be executed by the thread pool thread must be passed in as parameter to the "QueueUserWorkItem" as an instance of "WaitCallback" delegate. WaitCallback instance can reference any method that takes in a single parameter, of type "object". (The definition of WaitCallback is public delegate void WaitCallback(object state)).
Say, we have a method to be executed on the ThreadPool thread, named "Worker", and our logic inside the worker requires an integer value for its processing.
We would define our method to accept a parameter as "object", so that it can be referened as an instance of WaitCallback delegate.
The definition of the method would go as follows:
public void Worker(object parameter)
{
if (parameter is int)
{
int retrievedValue = (int)parameter;
// Use the retrieved value for further processing
}
}
The method that queues up the "Worker" method for execution on the thread pool thread would look something as below:
public void Queuer()
{
int valueToBePassed = 10;
// Some logic that might alter valueToBePassed
ThreadPool.QueueUserWorkItem(new WaitCallback(Worker), valueToBePassed);
}
Since "WaitCallback" delegate requires our "Worker" method to accept a single parameter of type object, the caller implicitly boxes the value type variable named "valueToBePassed" into an "object".
When the parameter is received by the "Worker" method, it first checks if the parameter received as type "object" indeed boxes an integer, and then explicitly un boxes it using an explicit cast, and then uses the value for its further processing.
This is one real world scenario where boxing and unboxing are useful.