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 แทน