Access Modifiers (ตัวกำหนดระดับการเข้าถึง) คืออะไร?
Access Modifiers กำหนดขอบเขต (scope) ที่สมาชิกของคลาส (Fields, Methods, Properties, Events) สามารถเข้าถึงได้ C# มี 6 ระดับการเข้าถึง
6 ระดับ Access Modifiers
| Modifier | ขอบเขตการเข้าถึง | คำอธิบาย |
|---|---|---|
public |
ทุกที่ (Unrestricted) | เข้าถึงได้จากที่ไหนก็ได้ ในและนอก Assembly |
private |
ภายในคลาสเดียวกัน | เข้าถึงได้เฉพาะในคลาสที่ประกาศ (Default ของ class members) |
protected |
คลาสเดียวกัน + คลาสลูก (Derived) | เข้าถึงได้ในคลาสเดียวกันและคลาสที่สืบทอดมา |
internal |
ใน Assembly เดียวกัน | เข้าถึงได้ในโปรเจกต์/Assembly เดียวกัน (Default ของ class/struct) |
protected internal |
Assembly เดียวกัน OR คลาสลูก | รวมขอบเขตของ protected และ internal (OR logic) |
private protected |
คลาสเดียวกัน + คลาสลูกใน Assembly เดียวกัน | รวมขอบเขตของ protected และ internal (AND logic) - C# 7.2+ |
ตารางสรุปการเข้าถึง
| public | protected | internal | protected internal | private protected | private
------------------------|--------|-----------|----------|-------------------|-------------------|--------
ภายในคลาสเดียวกัน | ✓ | ✓ | ✓ | ✓ | ✓ | ✓
คลาสลูกใน Assembly เดียวกัน | ✓ | ✓ | ✓ | ✓ | ✓ | ✗
คลาสอื่นใน Assembly เดียวกัน | ✓ | ✗ | ✓ | ✓ | ✗ | ✗
คลาสลูกใน Assembly อื่น | ✓ | ✓ | ✗ | ✓ | ✗ | ✗
คลาสอื่นใน Assembly อื่น | ✓ | ✗ | ✗ | ✗ | ✗ | ✗
ตัวอย่าง: Protected Access Modifier
using System;
namespace MySpecifiers
{
class Demo
{
protected string name = "Website";
protected void Display(string str)
{
Console.WriteLine("Tabs: " + str);
}
}
// คลาสลูก สืบทอดจาก Demo
class Test : Demo
{
static void Main(string[] args)
{
Test t = new Test();
// เข้าถึง protected member ได้ เพราะเป็นคลาสลูก
Console.WriteLine("Details: " + t.name);
t.Display("Product");
t.Display("Services");
t.Display("Tools");
t.Display("Plugins");
}
}
}
ผลลัพธ์
Details: Website
Tabs: Product
Tabs: Services
Tabs: Tools
Tabs: Plugins
ตัวอย่าง Access Modifiers อื่นๆ
Private (เข้าถึงได้เฉพาะในคลาสเดียวกัน)
public class BankAccount
{
private decimal balance = 0; // ซ่อนข้อมูลภายใน
public void Deposit(decimal amount)
{
if (amount > 0) balance += amount;
}
public decimal GetBalance()
{
return balance; // เข้าถึงผ่าน public method
}
}
Internal (เข้าถึงได้ใน Assembly เดียวกัน)
// ใน Assembly เดียวกัน
internal class InternalHelper
{
internal void DoWork() { } // เรียกได้จากคลาสอื่นในโปรเจกต์เดียวกัน
}
Protected Internal (OR logic)
public class Base
{
protected internal void MyMethod() { }
}
// เรียกได้จาก:
// 1. คลาสลูกใน Assembly ใดๆ (protected)
// 2. คลาสอื่นใน Assembly เดียวกัน (internal)
Private Protected (AND logic - C# 7.2+)
public class Base
{
private protected void MyMethod() { }
}
// เรียกได้เฉพาะ:
// คลาสลูกที่อยู่ใน Assembly เดียวกันเท่านั้น
Best Practices
- Encapsulation: ใช้
privateสำหรับ fields, expose ผ่านpublicproperties - Inheritance: ใช้
protectedสำหรับสมาชิกที่คลาสลูกต้องใช้ - Assembly boundary: ใช้
internalสำหรับ helper classes ที่ไม่ต้องการ expose นอกโปรเจกต์ - Default: Class/Struct = internal, Members = private
สรุป
- 6 ระดับ: public, private, protected, internal, protected internal, private protected
- ควบคุมการเข้าถึงระหว่างคลาส Assembly และ Inheritance
- สำคัญสำหรับ Encapsulation และ API Design
- Default: class=internal, members=private