Introduction
Thanks to my readers for their tremendous support that motivated me to continue this OOP series further.
We have already covered nearly all the aspects of Inheritance and Polymorphism in C#. My article will highlight nearly all the aspects/scenarios of access modifiers in C#. We'll learn by doing a hands-on lab, not just by theory. We'll cover my favourite topic Constants in a very different manner by categorizing the sections in the form of “Labs”. My effort in this article will be to cover each and every concept to the related topic, so that at the end of the article we can confidently say that we understand “All about access modifiers in C#”. Just dive into OOP.

Image credit: Colocation centre
Prerequisites
I assume that my readers of this article have a very basic knowledge of C#. The reader need only know the definition of access modifiers. Last but not the least as I always wish that my readers should enjoy reading this article.
Roadmap
Let's recall our road map:

- Diving Into OOP (Day 1) : Polymorphism and Inheritance(Early Binding/Compile Time Polymorphism).
- Diving into OOP (Day 2) : Polymorphism and Inheritance (Inheritance).
- Diving into OOP (Day 3) : Polymorphism and Inheritance (Dynamic Binding/Run Time Polymorphism).
- Diving into OOP (Day 4) : Polymorphism and Inheritance (Abstract Classes).
- Diving into OOP (Day 5): All about access modifiers in C#(Public/Private/Protected/Internal/Sealed/Constants/Readonly Fields).
- Diving into OOP (Day 6) : Understanding Enum in C# (A Practical Approach).
- Diving into OOP (Day 7): Properties in C# (A Practical Approach).
- Diving into OOP (Day 8): Indexers in C# (A Practical Approach)
- Learning C# (Day 9): Delegates in C# (A Practical Approach)
- Learning C# (Day 10): Events in C# (A Practical Approach)
Let us take the definition from Wikipedia this time:
“Access modifiers (or access specifiers) are keywords in object-oriented languages that set the accessibility of classes, methods and other members. Access modifiers are a specific part of programming language syntax used to facilitate the encapsulation of components.”
Like the definition says, we can control the accessibility of our class methods and members through access modifiers, let us understand this in detail by taking every access modifier one by one.
Public, Private, Protected at class level
Whenever we create a class we always want to have the scope to decide who can access certain members of the class. In other words, we would sometimes need to restrict access to the class members. The one thumb rule is that members of a class can freely access each other. A method in one class can always access another method of the same class without any restrictions. When we talk about the default behavior, the same class is allowed complete access but no else is provided access to the members of the class. The default access modifier is private for class members.
Point to remember: The default access modifier is private for class members.
Let's do a hands-on lab. Just open your Visual Studio and add a console application in C# named AccessModifiers, you'll get a Program class file by default. In the same file add a new class named Modifiers and add the following code to it:
- using System;
- namespace AccessModifiers
- {
- class Modifiers
- {
- static void AAA()
- {
- Console.WriteLine("Modifiers AAA");
- }
- public static void BBB()
- {
- Console.WriteLine("Modifiers BBB");
- AAA();
- }
- }
- class Program
- {
- static void Main(string[] args)
- {
- Modifiers.BBB();
- }
- }
- }
So, your Program.cs file becomes like as shown in the code snippet above. We added a class Modifiers and two static methods AAA and BBB. Method BBB is marked as public. We call the method BBB from the Main method.The method is called directly by the class name because it is marked static.
When we run the application, we get the output as follows:
Output
Modifiers BBB
Modifiers AAA
BBB is marked public and so anyone is allowed to call and run it. Method AAA is not marked with any access modifier that automatically makes it private, that is the default. The private modifier has no effect on members of the same class and so method BBB is allowed to call method AAA. Now this concept is called member access.
Modify the Program class and try to access AAA as:
- class Program
- {
- static void Main(string[] args)
- {
- Modifiers.AAA();
- Console.ReadKey();
- }
- }
Output
'AccessModifiers.Modifiers.AAA()' is inaccessible due to its protection level
So, since the method AAA is private therefore no one else can have access to it except Modifiers class.
Now mark the AAA method as protected, our class looks as in the following.
Modifiers
- class Modifiers
- {
- protected static void AAA()
- {
- Console.WriteLine("Modifiers AAA");
- }
- public static void BBB()
- {
- Console.WriteLine("Modifiers BBB");
- AAA();
- }
- }
Program
- class Program
- {
- static void Main(string[] args)
- {
- Modifiers.AAA();
- Console.ReadKey();
- }
- }
Output
'AccessModifiers.Modifiers.AAA()' is inaccessible due to its protection level
Again the same output. We cannot access the method AAA even after we introduced a new modifier named protected. But BBB can access the AAA method because it lies in the same class.
Modifiers in Inheritance
Let's add one more class and make a relation of base and derived class to our existing class and add one more method to our base class. So our class structure will look something like the following.
Modifiers Base Class
- class ModifiersBase
- {
- static void AAA()
- {
- Console.WriteLine("ModifiersBase AAA");
- }
- public static void BBB()
- {
- Console.WriteLine("ModifiersBase BBB");
- }
- protected static void CCC()
- {
- Console.WriteLine("ModifiersBase CCC");
- }
- }
Modifiers Derive Class
- class ModifiersDerived:ModifiersBase
- {
- public static void XXX()
- {
- AAA();
- BBB();
- CCC();
- }
- }
Program Class
- class Program
- {
- static void Main(string[] args)
- {
- ModifiersDerived.XXX();
- Console.ReadKey();
- }
- }
Output
'AccessModifiers.ModifiersBase.AAA()' is inaccessible due to its protection level
Now in this case we are dealing with a derived class. Whenever we mark a method with the specifier, protected, we are actually telling C# that only derived classes can access that method and no one else can. Therefore in the method XXX we can call CCC because it is marked protected, but it cannot be called from anywhere else including the Main function. The method AAA is made private and can be called only from the class ModifiersBase. If we remove AAA from method XXX, the compiler will give no error.
Therefore now we are aware of three important concepts. Private means only the same class has access to the members, public means everybody has access and protected lies in between where only derived classes have access to the base class method.
All the methods for example reside in a class. The accessibility of that method is decided by the class in which it resides as well as the modifiers on the method. If we are allowed an access to a member, then we say that the member is accessible, else it is inaccessible.
Internal modifier at class level
Let's take one other scenario. Create a class library with a name “AccessModifiersLibrary” in your Visual Studio. Add a class named ClassA in that class library and mark the class as internal, the code will be as shown below.
AccessModifiersLibrary.ClassA
- namespace AccessModifiersLibrary
- {
- internal class ClassA
- {
- }
- }
Now compile the class and leave it. Its DLL will be generated in the ~\AccessModifiersLibrary\bin\Debug folder.
Now in your console application “AccessModifiers” was created earlier. Add the reference of the AccessModifiersLibrary library by adding its compiled DLL as a reference to AccessModifiers.
In Program.cs of the AccessModifiers console application, modify the Program class like shown below.
AccessModifiers.Program
- using AccessModifiersLibrary;
- namespace AccessModifiers
- {
- class Program
- {
- static void Main(string[] args)
- {
- ClassA classA;
- }
- }
- }
And compile the code.
Output
Compile time error: 'AccessModifiersLibrary.ClassA' is inaccessible due to its protection level
We encountered this error because the access specifier internal means that we can only access ClassA from AccessModifiersLibrary.dll and not from any other file or code. An internal modifier means that access is limited to the current program only. So try never to create a component and mark the class internal as no one would be able to use it.
And what if we remove the field internal from ClassA, will the code compile? As in the following.
AccessModifiersLibrary.ClassA
- namespace AccessModifiersLibrary
- {
- class ClassA
- {
- }
- }
AccessModifiers.Program
- using AccessModifiersLibrary;
- namespace AccessModifiers
- {
- class Program
- {
- static void Main(string[] args)
- {
- ClassA classA;
- }
- }
- }
Output
Compile time error: 'AccessModifiersLibrary.ClassA' is inaccessible due to its protection level
We again got the same error. We should not forget that by default if no modifier is specified, the class is internal. So our class ClassA is internal by default even if we do not mark it with any access modifier, so the compiler result remains the same.
Had the class ClassA been marked public, everything would have gone smoothly without any error.
Point to remember: A class marked as internal can only have its access limited to the current assembly only.
Namespaces with modifiers
Just for fun, let's mark the namespace of the AccessModifiers class library as public in the Program class.
Program
- public namespace AccessModifiers
- {
- class Program
- {
- static void Main(string[] args)
- {
- }
- }
- }
Compile the application.
Output
Compile time error: A namespace declaration cannot have modifiers or attributes
Point to remember: Namespaces as we see by default can have no accessibility specifiers at all. They are by default public and we cannot add any other access modifier including public again too.
Private Class
Let's do one more experiment and mark the class Program as private, so our code becomes:
- namespace AccessModifiers
- {
- private class Program
- {
- static void Main(string[] args)
- {
- }
- }
- }
Compile the code.
Output
Compile time error: Elements defined in a namespace cannot be explicitly declared as private, protected, or protected internal
So, point to remember: A class can only be public or internal. It cannot be marked as protected or private. The default is internal for the class.
Access modifiers for the members of the class
Now here is a big statement, that the members of a class can have all the preceding explained access modifiers, but the default modifier is private.
Point to remember: Members of a class can be marked with all the access modifiers and the default access modifier is private.
What if we want to mark a method with two access modifiers?
- namespace AccessModifiers
- {
- public class Program
- {
- static void Main(string[] args)
- {
- }
- public private void Method1()
- {
- }
- }
- }
Compile the code.
Output
Compile time error: More than one protection modifier
Therefore we can't mark a member with more than one access modifier often. But there are such scenarios too, we'll cover them in the next sections. Already defined types like int and object have no accessibility restrictions. They can be used anywhere and everywhere.
Internal class and public method
Create a class library with a class named ClassA marked internal and have a public method MethodClassA(), as in the following:
- namespace AccessModifiersLibrary
- {
- internal class ClassA
- {
- public void MethodClassA(){}
- }
- }
Add the reference of class library to our console application. Now in Program.cs of the console application, try to access that method MethodClassA of ClassA.
Program
- using AccessModifiersLibrary;
- namespace AccessModifiers
- {
- public class Program
- {
- public static void Main(string[] args)
- {
- ClassA classA = new ClassA();
- classA.MethodClassA();
- }
- }
- }
Output
Compile time errors
'AccessModifiersLibrary.ClassA' is inaccessible due to its protection level The type 'AccessModifiersLibrary.ClassA' has no constructors defined
'AccessModifiersLibrary.ClassA' is inaccessible due to its protection level
'AccessModifiersLibrary.ClassA' does not contain a definition for 'MethodClassA' and no extension method 'MethodClassA' accepting a first argument of type 'AccessModifiersLibrary.ClassA' could be found (are you missing a using directive or an assembly reference?)
So many errors. The errors are self-explanatory though. Even the method MethodClassA of ClassA is public, it could not be accessed in the Program class due to the protection level of ClassA, in other words internal. The type enclosing the method MethodClassA is internal, so no matter if the method is marked public, we cannot access it in any other assembly.
Public class and private method.
Let's make the class ClassA as public and method as private.
AccessModifiersLibrary.ClassA
- namespace AccessModifiersLibrary
- {
- public class ClassA
- {
- private void MethodClassA(){}
- }
- }
Program
- using AccessModifiersLibrary;
- namespace AccessModifiers
- {
- public class Program
- {
- public static void Main(string[] args)
- {
- ClassA classA = new ClassA();
- classA.MethodClassA();
- }
- }
- }
Output on compilation
'AccessModifiersLibrary.ClassA' does not contain a definition for 'MethodClassA' and no extension method 'MethodClassA' accepting a first argument of type 'AccessModifiersLibrary.ClassA' could be found (are you missing a using directive or an assembly reference?)
Now that we have marked our class Public, we still can't access the private method. So for accessing a member of the class, the access modifier of the class as well as the method is very important.
Public class and internal method
Make ClassA as public and MethodClassA as internal.
AccessModifiersLibrary.ClassA
- namespace AccessModifiersLibrary
- {
- public class ClassA
- {
- Internal void MethodClassA(){}
- }
- }
Program
- using AccessModifiersLibrary;
- namespace AccessModifiers
- {
- public class Program
- {
- public static void Main(string[] args)
- {
- ClassA classA = new ClassA();
- classA.MethodClassA();
- }
- }
- }
Output on compilation
'AccessModifiersLibrary.ClassA' does not contain a definition for 'MethodClassA' and no extension method 'MethodClassA' accepting a first argument of type 'AccessModifiersLibrary.ClassA' could be found (are you missing a using directive or an assembly reference?)
So an internal marked member means that no one from outside that DLL can access the member.
Protected internal
In the class library make three classes ClassA, ClassB and ClassC and place the code somewhat like this.
- namespace AccessModifiersLibrary
- {
- public class ClassA
- {
- protected internal void MethodClassA()
- {
- }
- }
- public class ClassB:ClassA
- {
- protected internal void MethodClassB()
- {
- MethodClassA();
- }
- }
- public class ClassC
- {
- public void MethodClassC()
- {
- ClassA classA=new ClassA();
- classA.MethodClassA();
- }
- }
- }
And in Program class in our console application, call the MethodClassC of ClassC.
Program
- using AccessModifiersLibrary;
- namespace AccessModifiers
- {
- public class Program
- {
- public static void Main(string[] args)
- {
- ClassC classC=new ClassC();
- classC.MethodClassC();
- }
- }
- }
Compiler output: The code successfully compiles with no error.
Protected internal modifier indicates two things, that either the derived class or the class in the same file can have access to that method, therefore in the above mentioned scenario, the derived class ClassB and the class in the same file, in other words ClassC, can access that method of ClassA marked as protected internal.
Point to remember: Protected internal means that the derived class and the class within the same source code file can have access.
Protected member
In our Program.cs in the console application, place the following code:
- namespace AccessModifiers
- {
- class AAA
- {
- protected int a;
- void MethodAAA(AAA aaa,BBB bbb)
- {
- aaa.a = 100;
- bbb.a = 200;
- }
- }
- class BBB:AAA
- {
- void MethodBBB(AAA aaa, BBB bbb)
- {
- aaa.a = 100;
- bbb.a = 200;
- }
- }
- public class Program
- {
- public static void Main(string[] args)
- {
- }
- }
- }
Compiler Output
Cannot access protected member 'AccessModifiers.AAA.a' via a qualifier of type 'AccessModifiers.AAA'; the qualifier must be of type 'AccessModifiers.BBB' (or derived from it)
Class AAA contains a protected member, in other words a. But to the same class no modifiers make sense. However as a is protected, in the derived class method MethodBBB, we cannot access it through AAA since aaa.a gives us an error. However bbb which looks like BBB does not give an error. To check this out, comment out the line aaa.a=100 in MethodBBB (). This means that we cannot access the protected members from an object of the base class, but from the objects of a derived class only. This is in spite of the fact that a is a member of AAA, in other words the base class. Even so, we still cannot access it. We also cannot access a from the method Main.
Accessibility Priority in inheritance
Program
- namespace AccessModifiers
- {
- class AAA
- {
- }
- public class BBB:AAA
- {
- }
- public class Program
- {
- public static void Main(string[] args)
- {
- }
- }
- }
Compiler Output
Compile time error: Inconsistent accessibility: base class 'AccessModifiers.AAA' is less accessible than class 'AccessModifiers.BBB'
The error again gives us one more point to remember.
Point to remember: between public and internal, public always allows greater access to its members.
The class AAA is by default marked internal and BBB that derives from AAA is made public explicitly. We got an error since the derived class BBB must have an access modifier that allows greater access than the base class access modifier. Here internal seems to be more restrictive than public.
But if we reverse the modifiers to both the classes in other words ClassA marked as public and ClassB internal or default, we eliminate the error.
Point to remember: The base class always allows more accessibility than the derived class.
Another scenario.
Program
- namespace AccessModifiers
- class AAA
- {
- }
- public class BBB
- {
- public AAA MethodB()
- {
- AAA aaa= new AAA();
- return aaa;
- }
- }
- public class Program
- {
- public static void Main(string[] args)
- {
- }
- }
Compiler output: Inconsistent accessibility: return type 'AccessModifiers.AAA' is less accessible than method 'AccessModifiers.BBB.MethodB()'
Here the accessibility of AAA is internal that is more restrictive than public. The accessibility of method MethodB is public that is more than that of the typeAAA. Now the error occurred because return values of a method must have greater accessibility than that of the method itself, which is not true in this case.
Point to remember: The return values of a method must have greater accessibility than that of the method itself.
Program





Mahesh AllePosted Jan 30, 2017, 7:39 AM
Excellent Article and it will helped me a lot to clear all my basics. Good work.
Gowtham RajamanickamPosted May 20, 2015, 1:16 AM
keep writing
Gowtham RajamanickamPosted May 20, 2015, 1:16 AM
good one
JASPALPosted Jul 23, 2014, 12:59 AM
"Diving into OOP (Day 6): All about Properties and Indexers in C#." IS NOT WORKING.
Kiran Kumar TalikotiPosted Jul 9, 2014, 2:21 AM
Great Article Akhil :) Keep it UP :)
Priti KumariPosted Jul 4, 2014, 4:44 AM
nice article
Manju lata YadavPosted Jul 4, 2014, 2:16 AM
A protected member is accessible within its class and by derived class instances. Internal types or members are accessible only within files in the same assembly. Your Article has printing mistake in table made for definition of Access Modifiers.
Prerana TiwariPosted Jul 3, 2014, 3:18 AM
Good article...........
RahulPosted Jul 2, 2014, 6:55 AM
Great and useful article with good and easy explanation
udeep kansalPosted Jul 2, 2014, 4:27 AM
Very nicely explained