Codectionary / Developer documentation / C#

Access Modifiers

Access modifiers control the visibility of classes, fields, methods, and properties from other parts of a program. C# provides public (accessible from anywhere), private (accessible only within the declaring class - the default for class members), protected (accessible within the class and its subclasses), internal (accessible only within the same assembly/project), and combinations like protected internal and private protected.

Syntax

public | private | protected | internal

Examples

The Main Access Levels

Demonstrating the most commonly used modifiers on fields within a class.

public class AccessDemo
{
    public int PublicField = 1;        // accessible from anywhere
    protected int ProtectedField = 2;   // accessible in this class + subclasses
    internal int InternalField = 3;      // accessible within the same project
    private int privateField = 4;         // accessible only within this class

    private void ShowAll()
    {
        // all four are accessible from inside the class itself
        Console.WriteLine(PublicField + ProtectedField + InternalField + privateField);
    }
}

Private Fields with Public Properties

The standard encapsulation pattern: hide data, expose controlled access through a property.

public class Account
{
    private double _balance;  // hidden from outside access

    public Account(double initialBalance)
    {
        _balance = initialBalance;
    }

    public double Balance => _balance;  // controlled read access

    public void Deposit(double amount)
    {
        if (amount > 0)
        {
            _balance += amount;
        }
    }
}

Account acc = new Account(100);
// acc._balance = -500;  // Error - private, can't be accessed directly
acc.Deposit(50);
Console.WriteLine(acc.Balance);  // 150

protected and Inheritance

protected members are accessible to subclasses, even outside the original assembly.

public class Vehicle
{
    protected int Speed;

    protected void Accelerate()
    {
        Speed += 10;
    }
}

public class Car : Vehicle
{
    public void Drive()
    {
        Accelerate();  // accessible because Car extends Vehicle
        Console.WriteLine($"Speed: {Speed}");
    }
}

Car car = new Car();
car.Drive();  // Speed: 10

Best practices

  • Default to private for fields, exposing access only through public properties when genuinely needed (encapsulation)
  • Use internal for types and members that should only be used within your own project/library, not exposed to external consumers
  • Use protected specifically when subclasses need access, and public only for the intentional external API of a class
  • Avoid the temptation to make everything public "just in case" - it removes the safety encapsulation is meant to provide

At a glance

Purpose
Applications on the .NET platform
File extension
.cs
Runs in
.NET runtime
Usually used with
.NET SDK and libraries

Specifications & further reading

Related C# documentation

Classes & Objects
A class is a blueprint for creating objects, bundling related data (fields/properties) and behavior (methods) together. C# is a fully object-oriented language - every application has at least one class, typically with a Main method as its entry point. An object is a specific instance of a class, created with the new keyword, with its own independent copy of the class's instance data.
Constructors
A constructor is a special method that runs automatically when an object is created with new, used to initialize the object's state. A constructor shares its name with the class and has no return type. C# supports constructor overloading (multiple constructors with different parameter lists) and constructor chaining with this(...), where one constructor calls another in the same class to avoid duplicating initialization logic.
Properties (get/set)
Properties are C#'s idiomatic way to expose class data through accessor-like syntax while still allowing controlled access via get and set. Unlike a plain public field, a property can validate a value before it's set, compute a value on the fly, or restrict access to read-only. Auto-implemented properties (using { get; set; } with no body) provide a concise shorthand when no custom logic is needed.
Inheritance & base
Inheritance lets a class (the derived or child class) reuse and extend the members of another class (the base or parent class), written as class Child : Parent. The base keyword gives access to the parent class's members from within the child, most commonly used to call the parent's constructor so the child doesn't have to duplicate its setup logic. Unlike some languages, C# only supports single class inheritance - a class can extend just one base class, but can implement multiple interfaces.