Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C#

ความแตกต่างระหว่าง Internal และ Private Modifiers ใน C#

Internal Access Modifier

เข้าถึงได้จาก ทุกคลาสใน Assembly เดียวกัน (Project เดียวกัน/Compiled Unit เดียวกัน)

ตัวอย่าง Internal

using System;

namespace RectangleApplication {
    class Rectangle {
        // Internal Fields - เข้าถึงได้ใน Assembly นี้
        internal double Length;
        internal double Width;
        
        // Internal Method (Default สำหรับ Class ใน Namespace เดียวกัน)
        internal double GetArea() {
            return Length * Width;
        }
        
        public void Display() {
            Console.WriteLine("Length: {0}", Length);
            Console.WriteLine("Width: {0}", Width);
            Console.WriteLine("Area: {0}", GetArea());
        }
    }
    
    // คลาสอื่นใน Assembly เดียวกัน เข้าถึง Internal ได้
    class ExecuteRectangle {
        static void Main(string[] args) {
            Rectangle r = new Rectangle();
            r.Length = 4.5;    // ✅ OK - Same Assembly
            r.Width = 3.5;     // ✅ OK
            r.Display();
            Console.ReadLine();
        }
    }
}

Private Access Modifier

เข้าถึงได้ เฉพาะในคลาสเดียวกันเท่านั้น (Strict Encapsulation)

ตัวอย่าง Private

using System;

namespace RectangleApplication {
    class Rectangle {
        // Private Fields - ซ่อนภายในคลาส
        private double Length;
        private double Width;
        
        // Public Method ตั้งค่า (Validation ได้)
        public void AcceptDetails() {
            Length = 10;
            Width = 15;
        }
        
        public double GetArea() {
            return Length * Width;
        }
        
        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.AcceptDetails(); // ✅ OK - Public Method
            
            // r.Length = 5; // ❌ Compile Error: Private!
            // r.Width = 10;  // ❌ Compile Error: Private!
            
            r.Display();
            Console.ReadLine();
        }
    }
}

ตารางเปรียบเทียบ

คุณสมบัติ Internal Private
ขอบเขตการเข้าถึง Assembly เดียวกัน (Project เดียวกัน) คลาสเดียวกันเท่านั้น
Derived Class ใน Assembly อื่น ❌ ไม่ได้ ❌ ไม่ได้
Derived Class ใน Assembly เดียวกัน ✅ ได้ ❌ ไม่ได้
External Assembly (DLL Reference) ❌ ไม่ได้ ❌ ไม่ได้
Unit Test Project (Assembly แยก) ❌ ไม่ได้ (ต้อง InternalsVisibleTo) ❌ ไม่ได้
Default สำหรับ Class Member ไม่ใช่ ✅ ใช่ (Default)
Default สำหรับ Class (Non-nested) ✅ ใช่ (Default) ไม่ใช่

Protected Internal และ Private Protected

Modifier ความหมาย เข้าถึงได้จาก
protected internal Protected OR Internal Derived Classes (任何 Assembly) + Same Assembly
private protected Private AND Protected Derived Classes ใน Same Assembly เท่านั้น

Internal และ Unit Testing

ปัญหา: Test Project เป็น Assembly แยก → เข้าถึง Internal ไม่ได้

แก้ไขด้วย InternalsVisibleTo Attribute

// ใน Assembly หลัก (AssemblyInfo.cs หรือ .csproj)
[assembly: InternalsVisibleTo("MyProject.Tests")]

// หรือใน .csproj

  
    <_Parameter1>MyProject.Tests
  


// ตอนนี้ Test Project เข้าถึง Internal ได้แล้ว

Best Practices

  • Private - Default Choice สำหรับ Fields/Implementation Details (Encapsulation)
  • Internal - สำหรับ Internal APIs ภายใน Assembly, Helper Classes, Factory Methods
  • Public - สำหรับ Public API ที่ต้องการ Expose นอก Assembly
  • Protected - สำหรับ Base Class Members ที่ Derived Class ต้องการเข้าถึง
  • หลีกเลี่ยง public fields - ใช้ Properties แทน