跳到主要内容

C# 接口

本章将介绍 C# 中的接口(Interface),包括接口定义、实现、以及接口的特性和最佳实践。

接口概述

什么是接口?

接口定义了契约,它指定了类必须实现的方法、属性、事件和索引器,但不提供实现。接口是一种抽象类型,用于定义类应该具有的行为。

// 接口定义
interface IComparable
{
int CompareTo(object obj);
}

interface IEnumerable
{
IEnumerator GetEnumerator();
}

接口 vs 抽象类

特性接口抽象类
多继承支持多个接口仅支持单一继承
实现可以包含默认实现(C# 8+)可以包含抽象成员
字段不能有实例字段可以有实例字段
构造函数没有构造函数可以有构造函数
访问修饰符成员默认 public可以有各种修饰符

接口的定义

基本语法

// 定义接口
interface IPlayer
{
// 方法
void Play();
void Pause();

// 属性
string Name { get; set; }
bool IsPlaying { get; }

// 事件
event EventHandler<PlayerEventArgs> StateChanged;
}

接口命名约定

// 接口前缀 I
interface IDisposable { }
interface IComparable { }
interface IEnumerable { }
interface ICollection { }

接口成员

interface IAnimal
{
// 方法(不能有实现,除非 C# 8+ default 成员)
void Speak();

// 属性
string Name { get; set; }
int Age { get; }

// 索引器
string this[int index] { get; set; }

// 事件
event EventHandler? Born;
}

接口的实现

显式实现

// 接口定义
interface IWriteable
{
void Write(string content);
}

interface IReadable
{
string Read();
}

// 类实现多个接口
class FileHandler : IWriteable, IReadable
{
private string _content = "";

// 实现 IWriteable
public void Write(string content)
{
_content = content;
}

// 实现 IReadable
public string Read()
{
return _content;
}
}

显式接口实现

interface IFirst
{
void Method();
}

interface ISecond
{
void Method();
}

// 使用显式实现避免冲突
class MyClass : IFirst, ISecond
{
// 实现 IFirst.Method
void IFirst.Method()
{
Console.WriteLine("IFirst.Method");
}

// 实现 ISecond.Method
void ISecond.Method()
{
Console.WriteLine("ISecond.Method");
}
}

// 使用
MyClass obj = new MyClass();
((IFirst)obj).Method(); // 输出: IFirst.Method
((ISecond)obj).Method(); // 输出: ISecond.Method

实现接口属性

interface IIdentifiable
{
string Id { get; }
string Name { get; set; }
}

class Person : IIdentifiable
{
public string Id { get; private set; }
public string Name { get; set; }

public Person(string id, string name)
{
Id = id;
Name = name;
}
}

实现接口事件

interface IObserver
{
void OnUpdate(string message);
}

class Publisher
{
public event EventHandler<string>? MessageSent;

public void SendMessage(string message)
{
Console.WriteLine($"发送: {message}");
MessageSent?.Invoke(this, message);
}
}

class Subscriber : IObserver
{
public void OnUpdate(string message)
{
Console.WriteLine($"收到: {message}");
}
}

接口的默认实现(C# 8+)

默认成员

interface ILogger
{
void Log(string message)
{
Console.WriteLine($"[LOG] {message}");
}

void Error(string message)
{
Console.WriteLine($"[ERROR] {message}");
}
}

// 可以直接使用默认实现
class ConsoleLogger : ILogger
{
// 可以选择重写或不重写
}

ConsoleLogger logger = new ConsoleLogger();
logger.Log("Hello"); // 使用默认实现

静态成员

interface IHelper
{
static string Version = "1.0.0";

static void PrintVersion()
{
Console.WriteLine($"Version: {Version}");
}
}

接口与多态

依赖接口而非实现

// 不好的设计
class OrderService
{
private SqlServerDatabase _db = new SqlServerDatabase();

public void Save(Order order)
{
_db.Save(order);
}
}

// 好的设计:依赖接口
class OrderService
{
private readonly IDatabase _db;

public OrderService(IDatabase database)
{
_db = database;
}

public void Save(Order order)
{
_db.Save(order);
}
}

依赖注入示例

// 定义接口
interface IDatabase
{
void Save(object data);
object Get(int id);
}

// 实现接口
class SqlServer : IDatabase
{
public void Save(object data)
{
Console.WriteLine("保存到 SQL Server");
}

public object Get(int id)
{
return new { };
}
}

class MongoDB : IDatabase
{
public void Save(object data)
{
Console.WriteLine("保存到 MongoDB");
}

public object Get(int id)
{
return new { };
}
}

// 使用
class Service
{
private readonly IDatabase _database;

public Service(IDatabase database)
{
_database = database;
}
}

// 运行时注入不同实现
var service1 = new Service(new SqlServer());
var service2 = new Service(new MongoDB());

接口的继承

interface IReadable
{
string Read();
}

interface IWritable
{
void Write(string content);
}

// 接口继承接口
interface IFile : IReadable, IWritable
{
void Delete();
}

// 类实现接口
class File : IFile
{
public string Read() => "file content";

public void Write(string content) => Console.WriteLine(content);

public void Delete() => Console.WriteLine("deleted");
}

接口与协变/逆变

协变(C# 4+)

interface IProducer<out T>
{
T Produce();
}

class Animal { }
class Dog : Animal { }

class Producer : IProducer<Dog>
{
public Dog Produce() => new Dog();
}

// 协变允许
IProducer<Animal> producer = new Producer();

逆变(C# 4+)

interface IConsumer<in T>
{
void Consume(T item);
}

class Animal { }
class Dog : Animal { }

class Consumer : IConsumer<Dog>
{
public void Consume(Dog dog) => Console.WriteLine("consumed");
}

// 逆变允许
IConsumer<Animal> consumer = new Consumer();

常用 .NET 接口

IEnumerable 和 IEnumerator

interface IEnumerable<out T>
{
IEnumerator<T> GetEnumerator();
}

interface IEnumerator<out T>
{
bool MoveNext();
T Current { get; }
void Reset();
}

IDisposable

interface IDisposable
{
void Dispose();
}

// 使用 using
using (var resource = new Resource())
{
// 使用资源
} // 自动调用 Dispose

IComparable 和 IComparer

interface IComparable<in T>
{
int CompareTo(T other);
}

class Person : IComparable<Person>
{
public string Name { get; set; }
public int Age { get; set; }

public int CompareTo(Person other)
{
return Age.CompareTo(other.Age);
}
}

标记接口

// 空接口作为标记
interface ISerializable { }

class Data : ISerializable { }

// 检查
if (obj is ISerializable)
{
// 可以序列化
}

小结

  1. 接口定义:定义契约,不提供实现
  2. 接口实现:使用类实现一个或多个接口
  3. 显式实现:避免方法名冲突
  4. 默认实现:C# 8+ 支持带默认实现的接口
  5. 依赖注入:通过接口实现松耦合
  6. 协变/逆变:泛型接口的类型安全性

练习

  1. 创建一个 IComparable 接口的实现类
  2. 设计一个简单的依赖注入容器
  3. 使用接口实现策略模式
  4. 实现一个支持排序和筛选的集合类