Scope and Boxing in C#

Welcome to yet another exciting article on C#. In the previous article, we discussed different types of Streams along with their usage. In this article, I am going to cover the concepts of scope and boxing in C#.

Scope in C#

In C#, the term scope is associated with a couple of things, the scope of a variable and scope of a method. The scope a variable defines its visibility or accessibility in the rest of the code. In simplest words, scope defines areas in the code where a variable can be read and written. The scope of a method identifies the areas in the code where it can be called.

There are multiple ways of defining the scope of a variable and a method. It depends on where in the code you want your variable to be accessed and where you want your method to be called. There are four different types of scopes in c#. They are as follows:

  1. Public: Variables and methods declared public can be accessed anywhere.
  2. Private: These variables and methods are only accessible within the class in which they are created.
  3. Protected: Accessible within the class and the child classes of the class in which they are declared.
  4. Internal: Accessible only within the same assembly/project

The scopes mentioned above are also known as access modifiers in C# since they modify the access of variables and methods.

Variable Scope

Let’s have a look at our first example to see how these access modifiers are used to specify the variable scope.

class Program
{
    static void Main(string[] args)
    {
        Test testClass = new Test();

        Console.WriteLine(testClass.accessedString);
        Console.WriteLine(testClass.nonAccessedString); // Will not work due to the protection level
    }
}


class Test
{
    public string accessedString;
    private string nonAccessedString;
}

You do not need to execute the above

code to see how access modifiers work. Actually, your compiler won’t let you execute the code with invalid scope access. If you look at the code above, you should see two classes Program and Test. Inside the Test class, two string type variables are declared. The scope of the first variable is declared public while the second variable is declared private. Inside the main class, an object of test class is initialized.

When you access the public string variable via the test class object you can see that compiler doesn’t generate an error. However, if you try to access the private string variable of test class within the main class, the compiler generates an error which says that variable “is inaccessible due to its protection level.”

Now let’s have a look at another example to see what “Protected” access modifier does.

class Program
{
    static void Main(string[] args)
    {
        Test testClass = new Test();

        Console.WriteLine(testClass.protectedString); // Will not work because string is protected
    }
}


class Test
{
    protected string protectedString;
}

class Test2 : Test
{
    public void ProtectedTest()
    {
        Console.WriteLine(protectedString);
    }
}

Pay close attention to the code in above snippet. Three classes have been declared in the code: Program, Test, and Test2. The Test2 class inherits from the Test class. The Test class contains a protected string type variable. Now, if you want to access the protected string variable in Program class, the compiler will generate an error. However, in the Test2 class, you can access the protected variable of the test class without even creating an object of the test class. This is because all the protected variables are directly accessible within the child classes.

The scope of a variable also depends on the code block where it is declared. For instance, if you have declared a variable inside an if block, it will only be accessible throughout the if block and not outside it. However, if you declare a variable outside the if block but inside some method, it will be accessible within the method as well as within the inner if block. Take a look at the following code.

public static void DisplayVariable()
{
    int outerVariable = 10;
    if (true)
    {
        int innerVariable = 5;
        Console.WriteLine(outerVariable); // outerVariable is accessible here
    }

    Console.WriteLine(innerVariable); // Will Not Work. innerVariable is not accessible here
}

In the above code, an integer variable outerVariable is initialized within the DisplayVariable method. This variable is initialized outside the if block. This variable is also accessible within the if block. Similarly, inside the if block a variable named “innerVariable” is initialized. However, if you want to access it inside the DisplayVariable method, before or after the if block, you won’t be able to access it. It is only visible within the if block.

Method Scope

Method scope is similar to variable scope. The only difference is that variable scope defined where a variable can be read and written while method scope defines from where in the code a method can be called. Let’s have a look at a simple example of method scope.

class Program
{
    static void Main(string[] args)
    {
        Test testClass = new Test();

        testClass.publicMethod();
        testClass.privateMethod(); // Will not work
    }
}


class Test
{
    public void publicMethod()
    {
        Console.WriteLine("This is a public method");
    }

    private void privateMethod()
    {
        Console.WriteLine("This is a private method");
    }
}

In the above code, a public and private method is declared inside a test class. In the main method, a test class object is initialized. Now you can access the public method of the test class via this newly created testClass object. However, if you try to access the private method of the test class, the compiler will generate a protection level error.

Boxing in C#

Before diving into boxing and unboxing in C# you need to know the concept of value types and reference types in .NET.

Value Types

Value type variables are variables that store values on the stack. The variables hold actual memory address of the value it holds. If this variable is copied into a new value type variable, a new memory address is created for the variable, and the copied value is stored in this memory address. Changing the value for any of the value type variables has no impact on the value of the other variable. All the primitive data types and struct types are stored by value.

Reference Types

Reference type variables are those variables which store a reference to the actual memory location of the data. Reference type variables are stored on the stack but the actual data to which these variables refer is stored in the heap. If a reference type variable is copied into another variable, the reference to the memory location of the actual data is copied. Therefore, if the value stored in the memory location is updated via the copied variable, the data for actual variable is also updated. All the objects are stored by reference.

Now you have got basic understand of reference type and value types. Let’s see what is boxing and unboxing in C#.

Boxing vs Unboxing in C#

Boxing refers to the process of converting a value type variable to a reference type. Boxing is implicit, which means that you don’t have to do any type casting to convert a value type variable to a reference type.

Unboxing is the reverse of boxing. It refers to the process of converting a reference type variable into a value type. Unboxing is explicit, and you have to do type casting to store a reference type into a value type. Take a look at the following example.

int number = 43;
object obj = number; // Boxing. No casting needed

int number2 = (int) obj; // Unboxing. Type casting needed

You can see here that an integer “number” is being stored in an object “obj”. This is boxing and requires no casting. However, when you do the reverse, store the object “obj” to integer “number2”, you have to type-cast it explicitly to an integer.

In this article, we discussed what scope and boxing. If you found this article helpful be sure to check out my C# Roadmap.

As always, if you have any questions or comments, please leave a comment below or contact me via my contact page.