What is difference between internal and private modifiers in C#?

The internal and private access modifiers in C# control the visibility and accessibility of class members. Understanding their differences is crucial for designing well-structured applications with proper encapsulation.

The internal modifier allows access within the same assembly, while private restricts access to the same class only. Both serve different purposes in controlling member visibility.

Syntax

Following is the syntax for internal access modifier −

internal dataType memberName;
internal void MethodName() { }

Following is the syntax for private access modifier −

private dataType memberName;
private void MethodName() { }

Internal Access Modifier

The internal access modifier allows a class to expose its members to other classes and methods within the same assembly. Any member with internal access can be accessed from any class defined within the current application or assembly.

Internal vs Private Access Assembly Boundary Class A Class B internal members accessible Class C private members only within same class X

Example

using System;

namespace RectangleApplication {
    class Rectangle {
        //member variables with internal access
        internal double length;
        internal double width;

        double GetArea() {
            return length * width;
        }

        public void Display() {
            Console.WriteLine("Length: {0}", length);
            Console.WriteLine("Width: {0}", width);
            Console.WriteLine("Area: {0}", GetArea());
        }
    }//end class Rectangle

    class ExecuteRectangle {
        static void Main(string[] args) {
            Rectangle r = new Rectangle();
            r.length = 4.5;  // accessible because it's internal
            r.width = 3.5;   // accessible because it's internal
            r.Display();
        }
    }
}

The output of the above code is −

Length: 4.5
Width: 3.5
Area: 15.75

Private Access Modifier

The private access modifier allows a class to hide its members from other classes and methods. Only methods within the same class can access private members. This provides the highest level of encapsulation.

Example

using System;

namespace RectangleApplication {
    class Rectangle {
        private double length;  // private members
        private double width;

        public void AcceptDetails() {
            length = 10;
            width = 15;
        }

        public double GetArea() {
            return length * width;  // private members accessible within same class
        }

        public void Display() {
            Console.WriteLine("Length: {0}", length);
            Console.WriteLine("Width: {0}", width);
            Console.WriteLine("Area: {0}", GetArea());
        }
    }

    class ExecuteRectangle {
        static void Main(string[] args) {
            Rectangle r = new Rectangle();
            // r.length = 4.5;  // This would cause compilation error
            r.AcceptDetails();  // must use public method to set private data
            r.Display();
        }
    }
}

The output of the above code is −

Length: 10
Width: 15
Area: 150

Comparison Between Internal and Private

Aspect Internal Private
Accessibility Within the same assembly Within the same class only
Scope Assembly-level access Class-level access
Encapsulation Moderate encapsulation Highest encapsulation
Use Case Shared within application components Implementation details hiding

Practical Example Showing the Difference

using System;

namespace AccessModifierDemo {
    class BankAccount {
        internal string accountNumber;  // accessible within assembly
        private double balance;         // accessible only within this class

        public void SetBalance(double amount) {
            balance = amount;  // private member accessed within same class
        }

        public void ShowDetails() {
            Console.WriteLine("Account: {0}, Balance: {1}", accountNumber, balance);
        }
    }

    class BankSystem {
        static void Main(string[] args) {
            BankAccount account = new BankAccount();
            account.accountNumber = "ACC001";  // OK - internal member
            // account.balance = 1000;         // ERROR - private member
            account.SetBalance(1000);          // OK - using public method
            account.ShowDetails();
        }
    }
}

The output of the above code is −

Account: ACC001, Balance: 1000

Conclusion

The internal modifier provides assembly-level access while private restricts access to the class level only. Use internal for members that need to be shared within your application, and private for implementation details that should remain hidden from other classes.

Updated on: 2026-03-17T07:04:35+05:30

2K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements