Access Modifiers in C# are keywords which define the scope of accessibility of a member or a type. C# gives us 4 types of access modifiers : private, public, protected and internal. It also allows us to use combination of the above four access modifier to create 2 new access modifiers like protected-internal and private-protected.
The following six accessibility levels can be specified using the access modifiers:
The following image demonstrate the default accessibility applied to a type and which access type is allowed:
Note: Above image doesn't show
private protected
, this access specifier can be used byclass
, but it is avaialble in C# 7.2 and later.
Let's discuss all four access modifiers one by one.
The public keyword is an access modifier for types and type members. Public access is the most permissive access level. There are no restrictions on accessing public members, as in this example:
class DemoClass
{
public int z; // No access restrictions.
}
Take a look at an complete example, where two classes are declared, Test
and MainClass
. The public members x
and y
of Test are accessed directly from MainClass.
using System;
class Test
{
public int x;
public int y;
}
public class MainClass
{
public static void Main()
{
var t = new Test();
// Direct access to public members.
t.x = 10;
t.y = 15;
Console.WriteLine("Value of x="+t.x +" and y="+t.y);
}
}
Output:
Value of x=10 and y=15
Private access is the least permissive access level. Members or Objects that implement's private access modifier are accessible only inside a class or a structure. As a result, we can’t access them outside the class they are created, for example:
class Employee
{
private int i;
double d; // private access by default
}
Nested types in the same body can also access those private members.
If you try to access private memeber from outside the class or struct, you will get compile time error.
Example: In the give example, Employee
class contains two private data members, name
and salary
.
As private members, they cannot be accessed except by member methods. Public methods named GetName and Salary are added to allow controlled access to the private members. The name member is accessed by way of a public method, and the salary member is accessed by way of a public read-only property.
using System;
class Employee2
{
private string name = "Benjamin Clark";
private double salary = 100.0;
public string GetName()
{
return name;
}
public double Salary
{
get { return salary; }
}
}
public class PrivateTest
{
public static void Main()
{
var e = new Employee2();
// The data members are inaccessible (private), so
// they can't be accessed like this:
// string n = e.name;
// double s = e.salary;
// 'name' is indirectly accessed via method:
string n = e.GetName();
Console.WriteLine("Name="+n);
// 'salary' is indirectly accessed via property
double s = e.Salary;
Console.WriteLine("Salary="+s);
}
}
Output:
Name=Benjamin Clark
Salary=100
A protected member is accessible within its class and by derived class instances. So when "protected" keyword is used with class name, it means, memebers of that class can be accesses by class memebers or memebers of class which inherit it.
Let's consider a example
class Point
{
protected int x;
protected int y;
}
class DerivedPoint : Point
{
static void Main()
{
var dpoint = new DerivedPoint();
// Direct access to protected members.
dpoint.x = 10;
dpoint.y = 15;
Console.WriteLine("x = "+dpoint.x+ ", y = "+dpoint.y);
Console.ReadKey();
}
}
output:
x = 10, y = 15
In the above example, class DerivedPoint
is derived from Point
. Therefore, you can access the protected
members of the base class directly from the derived class.
If you change the access levels of x and y to private, the compiler will issue the error messages:
'Point.y' is inaccessible due to its protection level. 'Point.x' is inaccessible due to its protection level.
Internal types or members are accessible only within files in the same assembly, as in this example:
public class BaseClass
{
// Only accessible within the same assembly.
internal static int x = 0;
}
This is a very useful access modifier when you want to make any object public and yet do want to restrict its access only to the framework that you are coding. So, all internal objects are accessible by all areas of the same assembly.
For example, a framework for building graphical user interfaces could provide Control and Form classes that cooperate by using members with internal access. Since these members are internal, they are not exposed to code that is using the framework.
Let's consider a example, in which we will be using two class, base class have internal member while second class inherits it.
using System;
public class BaseClass
{
internal static int InternalMember = 0;
}
public class TestAccess
{
public static void Main()
{
var myBase = new BaseClass(); // Ok.
BaseClass.InternalMember = 444;
Console.WriteLine(BaseClass.InternalMember );
}
}
Output:
444
The protected internal keyword combination is a member access modifier. A protected internal member is accessible from the current assembly or from types that are derived from the containing class.
A protected internal member of a base class is accessible from any type within its containing assembly. It is also accessible in a derived class located in another assembly only if the access occurs through a variable of the derived class type.
Example:
using System;
public class BaseClass
{
protected internal int myValue = 0;
}
class TestAccess
{
void Access()
{
var baseObject = new BaseClass();
baseObject.myValue = 5;
}
}
class DerivedClass : BaseClass
{
static void Main()
{
var baseObject = new BaseClass();
var derivedObject = new DerivedClass();
// Error CS1540, because myValue can only be accessed by
// classes derived from BaseClass.
// baseObject.myValue = 10;
// OK, because this class derives from BaseClass.
derivedObject.myValue = 10;
Console.WriteLine(derivedObject.myValue);
Console.Read();
}
}
Output:
10
The private protected
access modifier is a combination of the private and protected keywords. We can access members inside the containing class or in a class that derives from a containing class, but only in the same assembly(project). Therefore, if we try to access it from another assembly, we will get an error.
Example:
A private protected member of a base class is accessible from derived types in its containing assembly only if the static type of the variable is the derived class type. For example, consider the following code:
public class BaseClass
{
private protected int myValue = 0;
}
public class DerivedClass1 : BaseClass
{
void Access()
{
var baseObject = new BaseClass();
// Error CS1540, because myValue can only be accessed by
// classes derived from BaseClass.
// baseObject.myValue = 5;
// OK, accessed through the current derived class instance
myValue = 5;
}
}
As pointed above private protected keyword is avaialble in C# 7.2 and later.
You may also like to read: