internal = Access Modifier ที่จำกัด Visibility ภายใน **Assembly เดียวกัน** (Project/Module ที่ Compile ร่วมกัน)
Accessibility Levels
| Modifier | เข้าถึงได้จาก |
|---|---|
private | ภายใน Class/Struct เดียวกัน |
private protected | ภายใน Class + Derived Classes ใน Assembly เดียวกัน |
internal | **ทุกที่ใน Assembly เดียวกัน** |
protected internal | Derived Classes (Any Assembly) + Assembly เดียวกัน |
public | ทุกที่ (Any Assembly) |
ตัวอย่าง: internal Class และ Members
using System;
namespace RectangleApplication {
// Internal Class - ใช้ได้เฉพาะใน Assembly นี้
internal class Rectangle {
internal double Length; // Internal Field
internal double Width; // Internal Field
// Private Method - ใช้ภายใน Class เท่านั้น
double GetArea() => Length * Width;
// Public Method - ใช้ได้จาก Assembly อื่น (ถ้า Class เป็น Public)
public void Display() {
Console.WriteLine($"Length: {Length}");
Console.WriteLine($"Width: {Width}");
Console.WriteLine($"Area: {GetArea()}");
}
}
// Class อื่นใน Assembly เดียวกัน — เข้าถึง Internal ได้
class ExecuteRectangle {
static void Main() {
Rectangle r = new Rectangle();
r.Length = 10.35; // ✅ OK: Internal Field
r.Width = 8.3; // ✅ OK: Internal Field
r.Display(); // ✅ OK: Public Method
// double a = r.GetArea(); // ❌ Error: Private Method
Console.ReadLine();
}
}
}
internal Class vs public Class
// Assembly A (MyLibrary)
internal class InternalHelper { } // ใช้ได้เฉพาะใน MyLibrary
public class PublicApi { } // ใช้ได้จาก Assembly B, C, ...
// Assembly B (Consumer) - References MyLibrary
// var h = new InternalHelper(); // ❌ Inaccessible
var api = new PublicApi(); // ✅ OK
internal protected (Protected Internal)
public class Base {
protected internal void Helper() { } // Derived Classes (Any Assembly) + Same Assembly
}
class DerivedInSameAssembly : Base {
void Test() { Helper(); } // ✅ OK: Derived + Same Assembly
}
class DerivedInOtherAssembly : Base {
void Test() { Helper(); } // ✅ OK: Derived (Different Assembly)
}
class UnrelatedInSameAssembly {
void Test() {
new Base().Helper(); // ✅ OK: Same Assembly
}
}
class UnrelatedInOtherAssembly {
void Test() {
// new Base().Helper(); // ❌ Inaccessible
}
}
Friend Assemblies (InternalVisibleTo)
อนุญาต Assembly อื่นเข้าถึง Internal Members
// Assembly A (MyLibrary)
[assembly: InternalsVisibleTo("MyLibrary.Tests")]
[assembly: InternalsVisibleTo("MyLibrary.InternalTools")]
internal class SecretClass { } // Tests และ Tools เข้าถึงได้
ใช้สำหรับ Unit Testing Private/Internal Logic
Best Practices
- Default ไปที่
internalสำหรับ Class — เปิดpublicเฉพาะ API ที่ต้องการ Expose - ใช้
InternalsVisibleToสำหรับ Test Project — ทดสอบ Internal Logic ได้โดยไม่ Expose สู่ Public - หลีกเลี่ยง
publicFields — ใช้ Properties internalบน Members ในpublicClass: ซ่อน Implementation Detail จาก Consumer