What are Access modifiers in C#?
Access modifiers in C# are keywords that determine the accessibility of a class, method, field, or property from other parts of the program. It's important to use the appropriate access modifier for each class member, depending on its intended accessibility. Access modifiers help you control the visibility and accessibility of your code, which can improve its security, maintainability, and readability. By using the right access modifiers, you can ensure that your code is accessible only to the parts of your program that need it while keeping it hidden from unauthorized access.
Advantage of C# Access Modifiers
- Improved security: By restricting access to certain class members, you can prevent unauthorized access to sensitive data or functionality in your program.
- Improved encapsulation: Encapsulation is the practice of hiding the implementation details of a class and exposing only a well-defined set of methods and properties to the outside world. Access modifiers help you enforce encapsulation by controlling the visibility of your class members.
- Better maintainability: By using access modifiers to limit the scope of your class members, you can reduce the risk of unintended side effects when modifying your code.
- Better readability: By using access modifiers to explicitly specify the intended visibility of your class members, you can make your code easier to understand and reason for other developers.
C# has five access modifiers
- public
- private
- protected
- internal
- protected internal
1. public access modifier
The public access modifier allows the class, method, field, or property to be accessed from anywhere in the program. It has the widest scope of accessibility. The public access modifier is the most permissive access level in C#. Members declared as public can be accessed from anywhere in the program, including from other classes and assemblies. Fields, methods, properties, classes, and interfaces can all be declared public. When a class is declared public, its name must match the name of the file it's defined in. It's generally considered good practice to only expose what is necessary to the public in order to maintain encapsulation and minimize potential side effects.
Using public can make it easier to work with objects and data throughout your program, as you can access and modify properties and methods from anywhere. However, this can also lead to potential security or maintenance issues if not used carefully.
Think of it like a public park where anyone can enter and use the facilities. Similarly, a public
member is accessible to all parts of the program and can be used by any class or code that has access to the member's containing class.
Examples of Public Access Modifiers.
using System;
// public Class Calculator
public class Calculator
{
// public Method Add
public int Add(int x, int y)
{
return x + y;
}
// public Method Subtract
public int Subtract(int x, int y)
{
return x - y;
}
}
class Program
{
static void Main(string[] args)
{
Calculator myCalculator = new Calculator();
int result1 = myCalculator.Add(5, 7); // result1 will be 12
int result2 = myCalculator.Subtract(10, 3); // result2 will be 7
Console.WriteLine("Addition result: " + result1);
Console.WriteLine("Subtraction result: " + result2);
}
}
using System;
public class Person
{
// Public Fields
public string Name;
public int Age;
}
class Program
{
static void Main(string[] args)
{
Person p = new Person();
p.Name = "John";
p.Age = 30;
Console.WriteLine("Name: " + p.Name);
Console.WriteLine("Age: " + p.Age);
}
}
using System;
public class Person
{
private string name;
// Public Properties Name
public string Name
{
get { return name; }
set { name = value; }
}
private int age;
// Public Properties Age
public int Age
{
get { return age; }
set { age = value; }
}
}
class Program
{
static void Main(string[] args)
{
Person p = new Person();
p.Name = "John";
p.Age = 30;
Console.WriteLine("Name: " + p.Name);
Console.WriteLine("Age: " + p.Age);
}
}
using System;
// Public interface IShape
public interface IShape
{
public double GetArea();
}
public class Rectangle : IShape
{
public double Length;
public double Width;
public double GetArea()
{
return Length * Width;
}
}
class Program
{
static void Main(string[] args)
{
Rectangle r = new Rectangle();
r.Length = 5;
r.Width = 10;
double area = r.GetArea();
Console.WriteLine("Area: " + area);
}
}
2. Private access modifiers
The Private modifier restricts the visibility of a class member to only within the same class where it is defined. Private members cannot be accessed or modified by any code outside the class, including its subclasses. Using private
helps to enforce encapsulation by hiding implementation details from external code. Private members can only be accessed indirectly through public methods that provide a controlled interface to the class. Private members are often used to store data or perform operations that are internal to the class and do not need to be exposed to external code. It is a best practice to use Private for all class members that are not part of the public interface of the class.
Imagine you have a personal bank account with a certain amount of money. The bank account is like a class, and the money in it is a private member.
- The private member (money) is like the cash you have in your account. It is not visible or accessible to anyone else.
- You are the only one who can directly interact with your money by performing transactions (e.g., withdrawing or depositing).
- Other people cannot directly access or modify the money in your account.
Think of it like having a private room in your house that is only accessible to you. Only you have the key to enter and use the room. Similarly, a private
member is only accessible and usable within its own class.
Examples of Private Access Modifiers.
using System;
namespace ExampleNamespace
{
public class Car
{
private string make;
private string model;
private int year;
private void PrivateMethod()
{
Console.WriteLine("This is a private method");
}
private string PrivateProperty { get; set; }
private class InnerClass
{
public void Display()
{
Console.WriteLine("This is the inner class");
}
}
public void SetMake(string make)
{
this.make = make;
}
public void SetModel(string model)
{
this.model = model;
}
public void SetYear(int year)
{
this.year = year;
}
public void Display()
{
Console.WriteLine("Make: " + make);
Console.WriteLine("Model: " + model);
Console.WriteLine("Year: " + year);
}
public void AccessPrivateMembers()
{
PrivateMethod();
InnerClass inner = new InnerClass();
inner.Display();
}
}
public class Program
{
public static void Main(string[] args)
{
Car car = new Car();
car.SetMake("Toyota");
car.SetModel("Camry");
car.SetYear(2021);
car.Display();
car.AccessPrivateMembers();
}
}
}
3. protected access modifiers
The protected access modifier in C# allows a class member (such as a field, property, or method) to be accessed within the class where it is defined, as well as within any derived classes. However, it restricts access from code outside the class hierarchy. By using protected, you can hide certain implementation details or data from external code while allowing derived classes to access and utilize those members. It helps maintain encapsulation by providing controlled visibility within the class hierarchy.
Key Points of the protected modifier:
Accessibility: protected members can only be accessed within the same class and its derived classes.
Inheritance: It is primarily used in inheritance scenarios to provide access to inherited members in derived classes.
Encapsulation: By marking members as protected, you ensure they are only accessible within the class hierarchy, maintaining encapsulation.
Usage: protected members are often used for internal operations or data storage that don't need direct access from external code.
Best Practice: It is recommended to use protected for class members that are not part of the public interface.
Think of it like having a secret room within your house that only family members can enter. The room is accessible to you (the class) and your immediate family (derived classes), but it is not open to the general public (external code).
Example of Protected Access Modifier.
using System;
public class Animal
{
protected string name; // protected field
protected void DisplayInfo() // protected method
{
Console.WriteLine($"Name: {name}");
}
}
public class Dog : Animal
{
public Dog(string name)
{
this.name = name; // accessing the protected field from the base class
}
public void Bark()
{
DisplayInfo(); // accessing the protected method from the base class
Console.WriteLine("Woof!");
}
}
public class Program
{
public static void Main()
{
Dog myDog = new Dog("Max");
myDog.Bark(); // calling a public method that accesses protected members
// The following lines will not compile because the protected members are not accessible outside the class hierarchy:
// myDog.name = "Buddy";
// myDog.DisplayInfo();
}
}
4. Internal access modifiers
In C#, the internal access modifier is used to specify that a class, method, property, or any other class member is accessible only within its assembly. An assembly is a compiled unit of code that can be a DLL (Dynamic Link Library) or an executable file (EXE). It represents a logical grouping of related types and resources. By marking a class or member as internal, you are restricting its visibility to only within the assembly in which it is defined.
In simple terms, the internal access modifier in C# means that a class or member can only be accessed within the same "box" or "package" of code.
Imagine your code as a collection of boxes, and each box represents an assembly (DLL or EXE file). When you mark something as internal, it's like putting it inside a box that can only be opened from within that box. Other boxes (assemblies) cannot access what's inside that box.
By using the internal modifier, you can hide certain parts of your code from external components and provide a clear boundary for what should and should not be accessed outside of your assembly. It helps in keeping the implementation details separate and maintaining the integrity of your code.
Example of Internal Access Modifier.
using System;
public class Animal
{
internal string name; // internal field
internal void DisplayInfo() // internal method
{
Console.WriteLine($"Name: {name}");
}
}
public class Dog : Animal
{
public Dog(string name)
{
this.name = name; // accessing the internal field from the base class
}
public void Bark()
{
DisplayInfo(); // accessing the internal method from the base class
Console.WriteLine("Woof!");
}
}
public class Program
{
public static void Main()
{
Dog myDog = new Dog("Max");
myDog.Bark(); // calling a public method that accesses internal members
// The following lines will not compile because the internal members are not accessible outside the assembly:
// myDog.name = "Buddy";
// myDog.DisplayInfo();
}
}
5. Protected Internal
The protected internal access modifier in C# is a combination of both protected and internal. It allows access to a class member from within the same assembly (like internal) and from derived classes outside the assembly (like protected).
what protected internal means:
- protected allows access to a member within the same class or derived classes, regardless of the assembly.
- internal allows access to a member within the same assembly.
- By combining these modifiers, protected internal allows access to a member in the following scenarios:
- From within the same class.
- From within derived classes, even if they are in a different assembly.
- From within the same assembly, regardless of the inheritance relationship.
Think of it like sharing a secret password with a group of friends (the assembly). Some friends (child classes) can access the secret with the password, even if they are from different neighborhoods (assemblies). And all friends within the same neighborhood (assembly) can access the secret without needing the password.
Another Example Imagine you have a special club called "The Secret Keepers," and you and your friends are members of this club. Each member has their own notebook to write down their secrets, but you also have a shared notebook where you write down secrets that are meant to be known within the club.
In this scenario
Your individual notebook represents the protected access modifier. Only you can access the secrets written in your notebook, and your closest friends who you trust implicitly (like your child classes), can also access those secrets. The shared notebook represents the internal access modifier. It contains secrets that are meant to be known within the club (the assembly). All members of the club, regardless of their relationship, can access the secrets written in the shared notebook.
Example of Protected Internal Access Modifier.
// Assembly A
using System;
public class Animal
{
protected internal string name; // protected internal field
protected internal void DisplayInfo() // protected internal method
{
Console.WriteLine($"Name: {name}");
}
}
// Assembly B
public class Dog : Animal
{
public Dog(string name)
{
this.name = name; // accessing the protected internal field from the base class
}
public void Bark()
{
DisplayInfo(); // accessing the protected internal method from the base class
Console.WriteLine("Woof!");
}
}
// Assembly A
public class Program
{
public static void Main()
{
Dog myDog = new Dog("Max");
myDog.Bark(); // calling a public method that accesses protected internal members
Console.WriteLine(myDog.name); // accessing the protected internal field directly
myDog.DisplayInfo(); // accessing the protected internal method directly
}
}
Summary
- The public provides the highest level of accessibility, allowing access from anywhere.
- Private restricts accessibility to only within the containing class.
- Protected allows access within the containing class and in derived classes.
- Internal enables access within the same assembly (project or DLL).
- Protected Internal provides access within the same assembly and derived classes, even from other assemblies.
These access modifiers help control the visibility and accessibility of classes, methods, properties, and fields, ensuring proper encapsulation and defining the boundaries of access for different components in your code.
I hope this blog post has offered you valuable insights into the concept of Access Modifiers in C#.
Thank you for reading, and happy coding!".