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

ทำไม Interface ใน C# ไม่สามารถระบุ Access Modifier ได้

เหตุผลหลัก: Interface เป็น Contract (สัญญา)

Interface กำหนด "ว่าต้องทำอะไรได้บ้าง" ไม่ใช่ "ทำอย่างไร"

  • วัตถุประสงค์: ให้ Type อื่นเข้าถึง Class/Struct ผ่าน Contract นี้
  • Member ทั้งหมดจึงเป็น Public โดยปริยาย (Implicitly Public)
  • การใส่ Access Modifier จะขัดกับหลักการ "Public Contract"

ประวัติความเปลี่ยนแปลง

Versionกฎ
C# 1.0 - 7.xMember ใน Interface ห้ามมี Access Modifier (Error CS0106)
C# 8.0+อนุญาต private, protected, internal สำหรับ Default Implementation และ Static Members

ตัวอย่าง C# 7.0 (Error)


interface IInterface
{
    // ❌ Compile Error: The modifier 'public' is not valid for this item
    public void Save(); 
    
    // ✅ OK - Implicitly Public
    void Save();
}

ตัวอย่าง C# 8.0+ (Valid)


interface IRepository<T>
{
    // Public - Standard Contract
    void Add(T entity);
    T GetById(int id);
    
    // Private - Helper สำหรับ Default Implementation
    private void Validate(T entity) { ... }
    
    // Protected - ให้ Derived Interface/Class ใช้ได้
    protected virtual void OnBeforeSave(T entity) { }
    
    // Internal - ใช้ภายใน Assembly เดียว
    internal void InternalCleanup() { }
    
    // Static Members (C# 8+)
    static IRepository<T> CreateDefault() => new DefaultRepository<T>();
    
    // Default Implementation (C# 8+)
    public void AddRange(IEnumerable<T> entities)
    {
        foreach (var e in entities) Add(e);
    }
}

Interface Access Modifiers (C# 8+)

Modifierใช้ได้กับความหมาย
publicMembers (Default)ส่วนของ Contract สาธารณะ
privateMethods, Static MembersHelper สำหรับ Default Implementation
protectedMethods, Propertiesเข้าถึงได้จาก Implementing Class
internalMembersเข้าถึงได้ใน Assembly เดียว
protected internalMembersProtected OR Internal
private protectedMembersProtected AND Internal (Same Assembly + Derived)

Interface Itself Access Modifier

Interface Declaration เองสามารถมี Access Modifier ได้:


// Namespace Level
public interface IPublicInterface { }     // เข้าถึงได้ทุกที่
internal interface IInternalInterface { } // เข้าถึงได้ใน Assembly เดียว

// Nested Interface
public class Outer
{
    private interface IPrivateInterface { } // เข้าถึงได้ใน Outer เท่านั้น
    protected interface IProtectedInterface { } // Outer + Derived Classes
}

Best Practice

  • ✅ Default: ไม่ใส่ Modifier (Implicitly Public) - Clear Contract
  • ✅ C# 8+: ใช้ private สำหรับ Helper Methods ใน Default Implementation
  • ✅ ใช้ internal สำหรับ Internal API
  • ❌ หลีกเลี่ยง protected ใน Interface (ทำให้ Complex)
  • ❌ อย่าใส่ public อย่างชัดเจน (Redundant, C# 7- Error)