接口聲明的核心約束
禁止包含的成員類型
- ? 數據成員(字段、常量)
- ? 靜態成員(靜態方法/屬性)
理由:接口僅定義契約,不涉及實現或狀態存儲。
允許的成員類型(僅非靜態函數成員)
- ? 方法(void Save())
- ? 屬性(string Name { get; set; })
- ? 事件(event EventHandler OnSaved)
- ? 索引器(object this[int index] { get; set; })
成員聲明規范
- 所有成員聲明必須省略實現代碼,以分號結尾
// 正確聲明
void Save();
string Name { get; set; }// 錯誤聲明(含實現體)
void Save() { } // 編譯錯誤!
命名與訪問控制規則
命名規范
強制前綴:接口名必須以大寫字母 I 開頭
public interface ISaveable { ... } // 正確
public interface Saveable { ... } // 不符合約定
訪問修飾符策略
對象 | 允許修飾符 | 默認訪問性 |
---|---|---|
接口本身 | public, protected, internal, private | 根據上下文 |
接口成員 | 禁止任何修飾符(隱式 public) | public |
public interface ILogger
{// 隱式public,不可添加修飾符void Log(string message); // private void Error(); // 非法聲明!
}
高級特性與示例
分部接口聲明
支持通過 partial 關鍵字拆分接口定義(適用于大型接口)
// File1.cs
public partial interface IDataProcessor
{void Validate();
}// File2.cs
public partial interface IDataProcessor
{void Process();
}
完整聲明示例
public interface IStorable
{// 屬性聲明 int Status { get; set; } // 方法聲明void Read(); void Write(string data); // 事件聲明 event Action OnModified; // 索引器聲明byte this[int index] { get; set; }
}
設計原則與陷阱規避
為何強制省略實現?
- 確保接口專注行為契約而非具體邏輯
- 避免與抽象類的職責混淆(抽象類可包含部分實現)
典型誤用場景
- 嘗試在接口中聲明字段 → 改用屬性封裝狀態
- 為接口成員添加 public → 冗余且導致編譯錯誤
最佳實踐建議
- 單一職責:每個接口聚焦單一功能(如 ISerializable, IDisposable)
- 命名語義化:I 前綴后使用形容詞/行為名詞(如 IComparable, IEnumerable)
關鍵總結
- 接口是純契約:無狀態、無靜態成員、無實現代碼
- 成員隱式公開 → 禁止顯式訪問修飾符
- 命名需以 I 開頭 → 強化類型語義
- 善用分部接口 → 提升大型項目可維護性