Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> C#

Các Access Modifier (Bộ chỉnh sửa truy cập) trong C#: 6 loại chi tiết

6 Access Modifiers trong C#

ModifierPhạm vi truy cậpKeyword
publicBất kỳ đâu (unrestricted)public
privateChỉ trong class/struct khai báoprivate
protectedClass khai báo + derived classesprotected
internalChỉ trong cùng assembly (project)internal
protected internalCùng assembly HOẶC derived class (union)protected internal
private protectedCùng assembly VÀ derived class (intersection)private protected

Chi tiết từng Modifier

1. public - Mở hoàn toàn


public class Person 
{
    public string Name = "Mark"; // Truy cập từ đâu cũng được
}

// Assembly khác
var p = new Person();
Console.WriteLine(p.Name); // OK

2. private - Đóng kín nhất


public class Person 
{
    private string _ssn = "123-45-6789"; // Chỉ truy cập trong Person
    
    public string GetMaskedSsn() => "***-**-" + _ssn.Substring(7);
}

// Assembly khác
var p = new Person();
// p._ssn; // ❌ Compile error
Console.WriteLine(p.GetMaskedSsn()); // OK

3. protected - Cho kế thừa


public class Person 
{
    protected string Name = "Mark"; // Class con truy cập được
}

public class Employee : Person 
{
    public void Print() => Console.WriteLine(Name); // OK
}

public class Program 
{
    static void Main() 
    {
        var e = new Employee();
        e.Print(); // OK: Mark
        
        var p = new Person();
        // p.Name; // ❌ Compile error - không phải derived class
    }
}

4. internal - Assembly boundary


// Project MyLibrary (Assembly A)
public class InternalService 
{
    internal void DoWork() { } // Chỉ Assembly A truy cập được
}

// Project MyApp (Assembly B) - reference MyLibrary
var svc = new InternalService();
// svc.DoWork(); // ❌ Compile error: inaccessible due to protection level

5. protected internal - Union (OR)


// Assembly A
public class Base 
{
    protected internal string Data = "Secret";
}

// Assembly A - Same assembly
class SameAssembly 
{
    void Test() 
    {
        var b = new Base();
        Console.WriteLine(b.Data); // OK - same assembly
    }
}

// Assembly B - Derived class
public class DerivedInOtherAssembly : Base 
{
    void Test() 
    {
        Console.WriteLine(Data); // OK - derived class
    }
}

// Assembly B - Non-derived
class Unrelated 
{
    void Test() 
    {
        var b = new Base();
        // b.Data; // ❌ Error - khác assembly KHÔNG phải derived
    }
}

6. private protected - Intersection (AND) - C# 7.2+


// Assembly A
public class Base 
{
    private protected string Secret = "Top Secret";
}

// Assembly A - Derived class
class DerivedInSameAssembly : Base 
{
    void Test() => Console.WriteLine(Secret); // OK: same assembly AND derived
}

// Assembly A - Non-derived
class UnrelatedInSameAssembly 
{
    void Test() 
    {
        var b = new Base();
        // b.Secret; // ❌ Error - không phải derived
    }
}

// Assembly B - Derived class
public class DerivedInOtherAssembly : Base 
{
    void Test() 
    {
        // Console.WriteLine(Secret); // ❌ Error - khác assembly
    }
}

Accessibility Matrix (Quick Reference)

Same TypeDerived Same AsmNon-Derived Same AsmDerived Diff AsmNon-Derived Diff Asm
public✅✅✅✅✅
protected internal✅✅✅✅❌
protected✅✅❌✅❌
internal✅✅✅❌❌
private protected✅✅❌❌❌
private✅❌❌❌❌

Best Practices

  • Default: private - Encapsulation, chỉ public khi cần thiết.
  • Public API: public cho types/members công khai.
  • Internal: Implementation details trong assembly (helpers, DTOs nội bộ).
  • Protected: Base class members dành cho derived class override.
  • Protected internal: Hiếm dùng - khi muốn derived class ở assembly khác truy cập.
  • Private protected: Rất hiếm - base class internal implementation cho derived trong cùng assembly.

Class/Struct Accessibility


// Top-level types: chỉ public hoặc internal
public class PublicClass { }      // Visible outside assembly
internal class InternalClass { }  // Chỉ trong assembly (default nếu không viết)

// Nested types: có thể dùng tất cả 6 modifiers
public class Outer 
{
    private class PrivateNested { }
    protected class ProtectedNested { }
    internal class InternalNested { }
    protected internal class ProtIntNested { }
    private protected class PrivProtNested { }
    public class PublicNested { }
}