1. Main Access Modifiers in C#
When you're coding, you often want to clearly control who and from where can see or change your variables and call your methods. It's like living in an apartment building: not every room is open to everyone. Some are only for residents, others just for maintenance folks.
In programming, this "access control" is handled with access modifiers. They define whether a class member (variable, field, method, property, etc.) is visible outside the class, in another class, or in another project. This is one of the main ways encapsulation is done in OOP: we hide the implementation details and only give out the "interfaces" we want others to use.
Here's a table with the main modifiers and a quick description:
| Modifier | Where is it visible? (in plain English) |
|---|---|
|
Everywhere (inside the project and outside — if you reference the assembly) |
|
Only inside the same class |
|
Same as private |
Looks scary? Actually, it's not hard at all. Let's check out some examples to see when to use which one.
2. The public Modifier — Anyone Can Come In
The public modifier makes your variable or method visible everywhere. If you declare a class member as public, you can access it from any other code that can see your class.
public class Person
{
public string Name;
public void SayHello()
{
Console.WriteLine($"Hi! My name is {Name}");
}
}
Now anywhere (in the same project or even in others, if you add a reference to the assembly), you can write:
Person p = new Person();
p.Name = "Alisa";
p.SayHello();
Pro tip: don't make everything public: that's a security risk for your code.
3. The private Modifier — Private Property!
The private modifier locks down access to the class contents: nobody outside can see what's there or change the data. By default, all fields and methods in C# classes are private if you don't specify another modifier.
public class Cup
{
private double volume; // Only the Cup class itself can see this field
public void Fill(double value)
{
volume = value; // Can use it inside the class
}
public double GetVolume()
{
return volume; // But nobody outside knows volume exists
}
}
Here, volume is hidden from everyone else, but any method inside Cup can use it. To get the volume, we provide a public method GetVolume().
4. Scope: Variables, Methods, and Classes
Scope is the part of your program where your name (variable, method, class) makes sense and is accessible.
- Local variables (declared inside a method or code block): only visible in that method or block.
- Method parameters: only visible inside the method.
- Class fields: visible everywhere in the class (depending on the access modifier).
- Classes: a nested class is only visible in the wrapper class if it's private, etc.
Let's look at a scope example:
public class Counter
{
private int count = 0; // visible everywhere in the class
public void Increment()
{
count++; // we can use the field
int temp = count * 2; // temp is only visible inside Increment
}
public int GetCount()
{
// temp is NOT visible here!
return count;
}
}
If you try to access temp inside GetCount() — you'll get an error.
5. Variable Shadowing
Shadowing is when you declare a variable (or parameter) with the same name in an inner scope as in an outer one. Inside that block, the "new" name shadows the old one, and you can't directly access the outer value anymore.
Shadowing example:
class ShadowDemo
{
int value = 10; // class field
void PrintValue()
{
Console.WriteLine(value); // 10 — class field
int value = 5; // local variable shadows the class field
Console.WriteLine(value); // prints 5, not 10
}
}
In this example, when we write int value = 5;, it shadows the class field with the same name inside the method. When you use value inside PrintValue(), the local variable is used, not the class field.
If you still need to access the class field, use the this keyword:
class ShadowDemo
{
int value = 10;
void PrintValue()
{
Console.WriteLine(value); // 10 — class field
int value = 5;
Console.WriteLine(value); // 5 — local variable
Console.WriteLine(this.value); // 10 — class field
}
}
Shadowing can be confusing, so it's a good idea to give your variables meaningful, different names — especially if you're working in big teams.
GO TO FULL VERSION