Lý do thiết kế
Interface là contract (hợp đồng) công khai - định nghĩa "cái gì" class phải làm, không phải "như thế nào". Mục đích: cho phép bên ngoài truy cập qua interface.
- Interface members mặc định là public (trước C# 8).
- Không cho phép
private,protected,internaltrên interface members (trước C# 8). - C# 8+ cho phép
private,protected,internalcho default implementation.
Trước C# 8: Luôn public
interface IRepository
{
void Save(); // Implicit public
// public void Save(); // ❌ Compile error: "The modifier 'public' is not valid for this item"
// private void Save(); // ❌ Compile error
}
C# 8+: Default Implementation & Access Modifiers
interface ILogger
{
// Public - default, có thể gọi từ interface variable
void Log(string message) => Console.WriteLine($"[LOG] {message}");
// Private - chỉ dùng nội bộ interface, KHÔNG gọi từ outside
private void WriteToFile(string msg)
{
File.AppendAllText("log.txt", msg);
}
// Protected - cho derived interface override
protected virtual void FormatMessage(ref string msg)
{
msg = $"[{DateTime.Now}] {msg}";
}
// Internal - chỉ trong assembly
internal void InternalLog(string msg) { }
// Static members (C# 8+)
static ILogger() { /* static init */ }
static void Helper() { }
}
Ví dụ: Private Helper trong Interface
interface ISerializer
{
string Serialize(object obj);
// Private helper - không lộ ra ngoài
private string Escape(string s) => s.Replace("\"", "\\\"");
// Default implementation dùng private helper
string Serialize(object obj)
{
var json = System.Text.Json.JsonSerializer.Serialize(obj);
return Escape(json);
}
}
Interface Access Modifiers (Class level)
Interface type có thể có access modifier:
// Internal interface - chỉ dùng trong assembly
internal interface IInternalService { }
// Public interface - dùng cross-assembly
public interface IPublicService { }
// Private/Protected interface - chỉ trong nested type
class Outer
{
private interface IPrivateInterface { }
protected interface IProtectedInterface { }
}
Explicit Implementation & Access
interface IService
{
void Execute();
}
class Service : IService
{
// Explicit implementation - implicitly private
void IService.Execute()
{
Console.WriteLine("Executing...");
}
}
// Usage
var s = new Service();
// s.Execute(); // ❌ Không thể gọi trực tiếp
IService svc = s;
svc.Execute(); // ✅ Chỉ qua interface
Tóm tắt quy tắc
| Context | Cho phép modifiers | Mặc định |
|---|---|---|
| Interface members (pre-C# 8) | Không có | public |
| Interface members (C# 8+) có body | private, protected, internal, static | public |
| Interface members (C# 8+) abstract | Không có | public |
| Interface type declaration | public, internal, private, protected (nested) | internal (non-nested) |
| Explicit implementation | Không có | private (implicit) |
Tại sao thiết kế như vậy?
- Contract clarity: Interface = public API surface.
- Substitution principle: Bất kỳ implementer nào đều phải public all members.
- Binary compatibility: Thay đổi access modifier = breaking change.
- C# 8 default implementations: Private/protected cho implementation details, không phải contract.