接口定义了一个契约 — 一组实现类必须提供的成员(方法、属性),传统上没有实现。一个类可以实现多个接口,这使它们成为 C# 中灵活、解耦、可测试设计的关键。
定义和实现接口
csharp
public interface IShape
{
double Area(); // a method signature (no body)
string Name { get; } // a property
}
public class Circle : IShape // implement the interface
{
public double Radius { get; set; }
public double Area() => Math.PI * Radius * Radius; // must implement
public string Name => "Circle";
}
接口(按约定命名为 IXxx)声明成员但不提供实现;实现它的类必须提供这些成员。(从 C# 8 开始,接口可以有默认实现,但契约角色仍是首要的。)
多接口(vs 单一继承)
csharp
public class Widget : IDrawable, ISerializable, IComparable<Widget>
{
// must implement ALL members of ALL interfaces
}
一个类可以实现多个接口(不同于单一类继承)— 这是 C# 在不相关的类型间共享能力的方式。
通过接口实现多态(关键优势)
csharp
// program to the INTERFACE — works with ANY implementation
List<IShape> shapes = new() { new Circle(), new Square() };
foreach (IShape s in shapes)
Console.WriteLine(s.Area()); // calls each type's implementation
void Process(IRepository repo) { } // depend on an interface, not a concrete class
常见的 .NET 接口和可测试性
csharp
IEnumerable<T>, IDisposable, IComparable<T>, IEquatable<T> // framework interfaces
// interfaces enable mocking in tests (depend on an interface, inject a mock)
public class Service(IEmailSender sender) { } // inject any IEmailSender (real or mock)
为什么这很重要
接口是优秀 C# 设计的核心,也是 .NET 框架和现代 C# 应用程序结构的基础,因此理解它们至关重要。
接口定义契约(类型能做什么)而不提供实现,一个类可以实现多个接口 — 这使它们成为 C# 实现灵活、解耦设计的首要工具,以及对单一继承限制的解答(在不相关的类型间共享能力)。
最重要的优势是实现松耦合和可测试性:通过依赖接口而不是具体类("面向接口编程"),代码变得灵活(交换实现)且高度可测试(在测试中注入模拟实现 — 接口被强调的主要原因,因为它们使依赖注入和单元测试变得可行)。
接口还支持多态(通过接口类型统一处理不同的实现)。
理解接口 — 定义契约、实现多个接口、为解耦和可测试性而面向接口编程,以及常见的 .NET 接口(IEnumerable、IDisposable 等)— 是设计可维护、可测试的 C# 应用程序和使用框架(该框架围绕接口构建)的重要知识。
由于接口是依赖注入、可测试性和灵活架构的基础 — 都是专业 C# 的特征 — 并且遍布 .NET,掌握它们是核心、频繁应用的知识,这区分了架构良好、可测试的 C# 与紧耦合代码,是反映良好设计原则理解的常见面试话题。
