Tuesday, 21 August 2018

C#: Access Modifiers

C# provides 5 access modifiers; access modifiers are used to protect the data. By using access modifiers, we can restrict whether other classes, other assemblies can able to access your data (or) not.

What is Assembly?
On successful compilation of any C# application, it generates a file, this file is called assembly. There are two types of assembly files present.
a.   DLL (Dynamic Link Library) : Class library projects are compiled to .dll files
b.   .exe files : Console application projects are compiled to .exe files

These Assembly files contain some intermediate language code. If you are from Java background, assume it like Java byte code.

Why this intermediate code?
Since all the .net framework languages generate same assembly code on successful compilation, applications that developed on different .net framework languages can easily communicate each other.

Let’s come back to the discussion on access modifiers. Following table summarizes each access modifier.

Access Modifier
Description
public
If any type (or) type variable declares with public access modifier, then it is available globally. It can be accessed in same assembly (or) from another assembly that references it.
private
The member variable declared as private are accessed by code in the same class (or) struct.
protected
The type or member can be accessed only by code in the same class or struct, or in a class that is derived from that class. protected can be used by any subclasses from any assembly.
internal
The type or member can be accessed by any code in the same assembly, but not from another assembly.
Protected internal
It is union of protected and internal. Members become accessible for inherited classes and for any classes inside the assembly.

Classes (or) structs that are defined directly inside the namespace (not inside a class, struct (or) any other type) can be either public (or) internal. If you don’t specify any access modifier, then the it uses internal as default access modifier.

Members of structs can be declared as public, internal, or private

Members of classes can be declared as public, protected internal, protected, internal, or private.

If you don’t specify access modifier for any members of type, then it takes private as default.

Private Access Modifier

Program.cs

using System;

class Program
{
    class Student
    {
        private String name;
        private int id;
    }

    static void Main(string[] args)
    {
        Student s1 = new Student();
        s1.name = "Hari krishna";
        s1.id = 123;

        Console.WriteLine("Name : {0}", s1.name);
        Console.WriteLine("Id : {0}", s1.id);
    }
}


Try to compile above program, compiler shows following kind of errors.



'Program.Student.name' is inaccessible due to its protection level

'Program.Student.id' is inaccessible due to its protection level



Since the members name, id are declared using private access modifier, they can’t be accessed outside of the class.



Internal Access Modifier

The type or member can be accessed by any code in the same assembly, but not from another assembly.

Program.cs

using System;

class Program
{
    class Student
    {
        internal String name;
        internal int id;
    }

    static void Main(string[] args)
    {
        Student s1 = new Student();
        s1.name = "Hari krishna";
        s1.id = 123;

        Console.WriteLine("Name : {0}", s1.name);
        Console.WriteLine("Id : {0}", s1.id);
    }
}

Output

Name : Hari krishna
Id : 123


Since the members name and id are defined using internal access modifier, they can be accessed inside the same assembly. Let’s us try to access the internal variables from different assembly.

Following is my current C# solution structure.

Let’s add new class library, ‘Assembly1’.

Right click on the solution ‘Hello World’ -> Add -> New Project.



Select ‘Class Library’, give the project name as Assembly1 and press OK.




Now the the solution ‘Hello World’ has to projects.

a.   Hello World

b.   Assembly1.






Define ‘Student.cs, file inside the Assembly1.


Right click on Assembly1 -> Add -> new Item.

Select the Class and give the class name as ‘Student.cs’.

Student.cs

using System;

namespace Assembly1
{
    Public class Student
    {
        internal String name;
        internal int id;
    }
}

Now we need to add this library ‘Assembly1’ to the main project ‘Hello World’. If you are form Java background, it is very similar how you add one jar file to your java application.

Adding Assembl1 project to Hello World.

Right click on ‘Hello World’ project -> Add -> Reference.


It shows currently available projects in the solution, select ‘Assembly1’ and press OK.


Now you can see ‘Assembly1’ is added as reference to ‘Hello World’ project.



Now update the Porgram.cs file in the ‘HelloWorld’ project like below.



Program.cs

using System;
using Assembly1;

class Program
{
    static void Main(string[] args)
    {
        Student s1 = new Student();
        s1.name = "Hari krishna";
        s1.id = 123;

        Console.WriteLine("Name : {0}", s1.name);
        Console.WriteLine("Id : {0}", s1.id);
    }
}


Try to run above program, compiler throws following error.

'Student.name' is inaccessible due to its protection level
'Student.id' is inaccessible due to its protection level

It is because, the members declared as internal are accessible inside the same namespace, you are trying to access the members outside of the name space, so compiler throws the error.

Protected access specifier
The type or member can be accessed only by code in the same class or struct, or in a class that is derived from that class. protected can be used by any subclasses from any assembly.

Update Student.cs like below.

Student.cs

using System;

namespace Assembly1
{
    public class Student
    {
        protected String name;
        protected int id;
    }
}

Update Program.cs like below.


Program.cs

using System;

public class MyStudent : Assembly1.Student
{
    
    public void updateStudent(String name, int id)
    {
        this.name = name;
        this.id = id;
    }

    public void printStudent()
    {
        Console.WriteLine("Name : {0}", name);
        Console.WriteLine("Id : {0}", id);
    }
}

class Program
{
    static void Main(string[] args)
    {
        MyStudent stud = new MyStudent();
        stud.updateStudent("Sudheer Sami", 543);
        stud.printStudent();
    }
}

Output

Name : Sudheer Sami
Id : 543

Notify Program.cs file, I defined new class ‘MyStudent’ it inherits the class ‘Assembly1.Student’. Since the members of Student class are declared as protected, the classes that inherits Student class can able to access these protected variables.


I hope with this you got some better understanding of access specifier, I am not going to explain about public and protected, internal, I am leaving it for your exercise.



Previous                                                 Next                                                 Home

No comments:

Post a Comment