Access modifiers are keywords in object-orientated programming (OOP) that are used to set the accessibility levels of types and type members. In C#, the accessibility level controls whether a type can be used within the current assembly or in other assemblies.
Access modifiers are used to assist with the implementation of the encapsulation OOP principle. C# provides four access modifiers (public
, private
, protected
and internal
) with the following accessibility levels.
public
private
protected
internal
protected internal
private protected
public
The public
keyword is an access modifier providing an accessibility level that is not restricted. Types and type members utilizing the public
modifier can be accessed everywhere, that is, there are no restrictions on accessing public members.
The type or member can be accessed by any other code in the same assembly or another assembly that references it.
Microsoft
Consider the below code base.
In the above code base, the Hero
class has a public
accessibility level. This class can be accessed everywhere, that is, it can be accessed anywhere in the current assembly, AccessModifier
, as well as any other assembly referencing the AccessModifier
assembly. Likewise, The Id
property and the Save
method are also publicly available whenever a new Hero
class is instantiated.
The public
access modifier is the most commonly used accessibility level. Since this access modifier has no restrictions, developers should be cautious when using it.
private
The private
keyword is an access modifier providing an accessibility level that is limited to the containing type.
The type or member can be accessed only by code in the same
Microsoftclass
orstruct
.
Consider the below code base.
From the above code base, id
, name
and Save()
can only be accessed within the Hero
class, that is, the containing class. Nested types in the same body can also access those private methods.
A compile time error will be thrown when trying to access a private member outside the containing class
or struct
in which it is declared.
When members in a class have no access modifier, the default access modifier will be private
.
protected
The protected
keyword is an access modifier providing an accessibility level that is limited to the containing class or types derived from the containing class.
The type or member can be accessed only by code in the same
Microsoftclass
, or in aclass
that is derived from thatclass
.
Consider the below code base.
In the above code base, the derived class, ChequeAccount
, has direct access to the AccountNumber
property from the base class, Account
.
internal
The internal
keyword is an access modifier providing an accessibility level that is limited to the current assembly.
The type or member can be accessed by any code in the same assembly, but not from another assembly.
Microsoft
Consider the below code base.
In the above code base, HeroRepository
is only accessible within the AccessModifier
assembly. The AccessModifier
assembly is referenced in the SomeOtherAssembly
, however, the SomeOtherAssembly
cannot instantiate the HeroRepository
due to the accessibility level of the HeroRepository
.
When a class has no access modifier specified, then the class will have a default access modifier of internal
.
Visual studio provides an easy way to make internal classes accessible to other assemblies for testing purposes. Refer to this article to set it up.
protected internal
protected internal
provides an accessibility level that is limited to the current assembly or types derived from the containing class.
The type or member can be accessed by any code in the assembly in which it’s declared, or from within a derived class in another assembly.
Microsoft
Consider the below code base.
From the above code base, Account
is a base class having a protected internal
integer AccountNumber
property. The derived class, ChequeAccount
, has direct access to the AccountNumber
property from the base class, Account
, since both the Account
and ChequeAccount
are contained within the same assembly, AccessModifier
.
The AccessModifier
assembly is referenced in the SomeOtherAssembly
, however, classes within the SomeOtherAssembly
deriving from the Account
base class cannot access the AccountNumber
property due to the accessibility level of the AccountNumber
.
Note that struct
members cannot be protected internal
because the struct
cannot be inherited.
private protected
private protected
provides an accessibility level that is limited to the containing class or types derived from the containing class within the current assembly.
The type or member can be accessed only within its declaring assembly, by code in the same class or in a type that is derived from that class.
Microsoft
Consider the below code base.
In the above code base, the derived class, ChequeAccount
, has direct access to the AccountNumber
property from the base class, Account
.
SavingsAccount
also has direct access to the AccountNumber
property since it is derived from Account
.
When a class is derived from Account
and the derived class is instantiated, then the AccountNumber
property cannot be accessed due to its accessibility level. This can be seen on lines 21 and 24 in the above code base.
However, when using classes derived from the containing class, the AccountNumber
property is accessible. This can be seen on line 26 and 27 where the SavingsAccount
derived class is instantiated within the SavingsAccount
class.
Note that struct
members cannot be private protected
because the struct
cannot be inherited.
Summary
Microsoft have provided an easy way for developers to implement certain OOP scenarios by using access modifiers with different accessibility levels, thus hiding unnecessary detail and only showing what is necessary during the implementation phase of a software program.
Further information on access modifiers and accessibility levels can be found at the following links:
Software versions used in this article
- Jetbrains Rider 2020.1.3