Every method, class, and property can be accessed differently. We don’t always want a certain class to be accessed from another library or even another class. To make this happen, we use something called access modifiers. We use C# access modifiers to define access to certain classes, methods properties, and more. This article explains how to use them with examples.
Table Of Contents
What are access modifiers?
In short: They specify the accessibility of types and type members. This way you can “hide” classes for people that use your code, or explicitly show the properties of a certain class.
There are 6 different C# access modifiers, namely:
| Public | Can be accessed from anywhere. Not ideal if you don’t want to expose a method or property to other classes. |
| Private | Can only be used in its own class or struct. |
| Protected | Can only be accessed from the same class and its derived classes. |
| Internal protected | Can be accessed from the same assembly and the derived class of the containing class from any other assembly. |
| Internal | Can only be accessed from within the same assembly. |
| Private protected | Can only be accessed within the same class, and its derived class within the same assembly. |
Examples
Private and public access modifiers
MovieService movieService = new();
movieService.SetTitle("The Matrix");
class MovieService
{
private int id;
public string title;
public void SetTitle(string title)
{
this.title = MakeUrlFriendly(title);
}
private string MakeUrlFriendly(string title)
{
return title
.ToLower()
.Replace(" ", string.Empty)
.Replace("#", string.Empty)
.Trim();
}
}
In this code, you can see a private int id. The movieService can’t access this property, initialized on line 1. The same goes for the method MakeUrlFriendly(). But they can be used inside the class MovieService, as shown on line 11.
The method SetTitle() and the property title are public and can be used outside the class, as shown in lines 1 and 2.
Public and private are the most used C# access modifiers.
Protected access modifier
Protected protects the type or member to be used directly, but the derived class can use it.
MovieService movieService = new();
//Console.WriteLine(movieService.title); // This won't work, because it's protected
Console.WriteLine(movieService.TheTitle);
class MovieService : TheMatrix
{
public string TheTitle => title;
}
class TheMatrix
{
protected string title = "The Matrix";
}
Line 2 tries to get the title from TheMatrix class on line 5. But that doesn’t work. On line 7 however, the title can be retrieved, because MovieService derives from the TheMatrix class.
You can also use protected methods:
MovieService movieService = new();
//Console.WriteLine(movieService.MakeUrlFriendly); // This won't work, because it's protected
Console.WriteLine(movieService.UrlFriendlyTitle);
class MovieService : TheMatrix
{
public string TheTitle => title;
public string UrlFriendlyTitle => MakeUrlFriendly();
}
class TheMatrix
{
public string title = "The Matrix";
protected string MakeUrlFriendly()
{
return this.title
.ToLower()
.Replace("#", string.Empty)
.Replace("?", string.Empty)
.Trim();
}
}
Internal access modifier
This one can’t be shown in one piece of code because you need a different assembly, which is a completely new project.
First look at the code below:
Movie movie = new()
{
Title = "The Muppets",
Rating = 10,
};
movie.GetDetails();
class Movie
{
internal string Title;
internal int Rating;
internal void GetDetails()
{
Console.WriteLine($"The Title of the movie is {Title}, which has a rating of {Rating}");
}
}
If you copy-paste this in a new console application it will work without problems.
Now, let’s change it up a bit. Let’s create a new project, a class library, and place the class Movie in that new project. Don’t forget to make the class public!
public class Movie
{
internal string Title;
internal int Rating;
internal void GetDetails()
{
Console.WriteLine($"The Title of the movie is {Title}, which has a rating of {Rating}");
}
}
Make a reference from your new class library to the console application and add the using for Movie.
using ATotallyDifferentProject;
Movie movie = new()
{
Title = "The Muppets",
Rating = 10,
};
movie.GetDetails();
Lines 5, 6, and 9 should give errors due to the protection levels.
As you notice, the Title and Rating can be used in the class Movie, but not in the initialized member in the console application.
Internal protected access modifier
Let’s take the previous code example, but change it a little bit:
public class Movie
{
public string Title;
internal int Rating;
internal protected string GetTitle => Title;
internal void GetDetails()
{
Console.WriteLine($"The Title of the movie is {Title}, which has a rating of {Rating}");
}
}
I made the Title public and added a property GetTitle, which is internal protected. Now, let’s go back to the console application:
using ATotallyDifferentProject;
SecondClass movie = new()
{
Title = "The Muppets",
};
// Console.WriteLine(movie.GetTitle); // Doesn't work.
Console.WriteLine(movie.TheOriginalTitle);
class SecondClass : Movie
{
public string TheOriginalTitle => GetTitle;
}
As you can see, in line 5 I set the movie title. On line 8 I tried to get the title by using movie.GetTitle, doesn’t work, because it’s protected. So I created a property in SecondClass class, TheOriginalTitle, which has access to the GetTitle of the class Movie.
Private protected access modifier
Private protected only works when the class is derived or inside the class itself. Take a look at the code example below for how it works:
SecondClass movie = new()
{
Title = "The Muppets",
};
//Console.WriteLine(movie.Rating); // Doesn't work.
Console.WriteLine(movie.GetTheRating);
class SecondClass : Movie
{
public int GetTheRating => Rating;
}
public class Movie
{
public string Title;
private protected int Rating = 5;
internal protected string GetTitle => Title;
internal void GetDetails()
{
Console.WriteLine($"The Title of the movie is {Title}, which has a rating of {Rating}");
}
}
Conclusion On C# Access Modifiers
Although there are some types of C# access modifiers, you won’t be using all of them a lot. The most common are public and private. In some cases, you might use the internal. I haven’t used all of them throughout my career.
It’s a good practice to know when and how to use the C# access modifiers. It could change the whole flow of your application. Understand their meaning and usage. Use the public or private or investigate more using search engines if you are not sure which C# access modifier you need to use. You can also check out the official documentation made by Microsoft.

