public class CustomList : IEnumerable, IEnumerator {
private int[] _items = { 1, 2, 3 };
private int _position = -1;
public IEnumerator GetEnumerator() {
Reset();
return this;
}
public bool MoveNext() => ++_position < _items.Length;
public object Current => _items[_position];
public void Reset() => _position = -1;
}
(2)使用yield关键字简化实现
C#通过yield return自动生成状态机,隐藏了迭代器的复杂性
编译器会生成一个嵌套类,管理Current、MoveNext()和状态机,适用于快速实现迭代逻辑。
csharp复制代码
public IEnumerable<char> GetAlphabet() {
for (char c = 'A'; c <= 'Z'; c++) {
yield return c; // 自动保存当前状态并返回元素
}
}
这种方式在内存效率和代码简洁性上优于手动实现
csharp复制代码
public IEnumerator GetEnumerator() {
for (int i = 0; i < 26; i++) {
yield return (char)('A' + i); // 动态生成字符序列
}
}
(3)泛型迭代器
通过IEnumerable<T>和IEnumerator<T>支持类型安全遍历
泛型迭代器避免了装箱/拆箱开销,提高了性能
csharp复制代码
public class GenericList<T> : IEnumerable<T> {
private T[] _items;
public IEnumerator<T> GetEnumerator() {
foreach (T item in _items) {
yield return item;
}
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
3、扩展与进阶
(1)与设计模式的结合
组合模式:迭代器可用于遍历树形结构的组合对象。
工厂方法模式:聚合类通过工厂方法创建特定类型的迭代器。
(2)异步迭代器
C# 8.0+支持await foreach异步遍历
适用于IO密集型操作(如网络请求)
csharp复制代码
public async IAsyncEnumerable<int> FetchDataAsync() {
while (hasMoreData) {
var data = await FetchNextPageAsync();
foreach (var item in data) {
yield return item;
}
}
}
(3)自定义迭代策略
通过扩展方法增强迭代功能
此方法可实现链式查询,类似LINQ
csharp复制代码
public static IEnumerable<T> Filter<T>(this IEnumerable<T> source, Func<T, bool> predicate) {
foreach (T item in source) {
if (predicate(item)) yield return item;
}
}
// 1. 定义中介者接口
public interface IChatMediator
{
void RegisterUser(User user);
void SendMessage(string message, User sender);
}
// 2. 具体中介者:管理用户及消息分发
public class ChatRoom : IChatMediator
{
private List<User> _users = new List<User>();
public void RegisterUser(User user)
{
_users.Add(user);
user.Mediator = this;
}
public void SendMessage(string message, User sender)
{
foreach (var user in _users.Where(u => u != sender))
{
user.Receive(message);
}
}
}
// 3. 抽象同事类
public abstract class User
{
public string Name { get; }
public IChatMediator Mediator { get; set; }
protected User(string name) => Name = name;
public abstract void Send(string message);
public abstract void Receive(string message);
}
// 4. 具体同事类
public class ChatUser : User
{
public ChatUser(string name) : base(name) { }
public override void Send(string message)
{
Console.WriteLine($"{Name}发送消息:{message}");
Mediator.SendMessage(message, this);
}
public override void Receive(string message)
{
Console.WriteLine($"{Name}收到消息:{message}");
}
}
// 客户端调用
var mediator = new ChatRoom();
var user1 = new ChatUser("Alice");
var user2 = new ChatUser("Bob");
mediator.RegisterUser(user1);
mediator.RegisterUser(user2);
user1.Send("Hello, Bob!");
(2)扩展实现:事件驱动中介者
结合C#的事件机制,实现松耦合交互
优势:进一步解耦中介者与同事类,适用于异步通信场景
csharp复制代码
// 定义事件参数
public class MessageEventArgs : EventArgs
{
public string Message { get; }
public User Sender { get; }
public MessageEventArgs(string message, User sender)
=> (Message, Sender) = (message, sender);
}
// 中介者通过事件通知
public class EventMediator
{
public event EventHandler<MessageEventArgs> MessageReceived;
public void Broadcast(string message, User sender)
=> MessageReceived?.Invoke(this, new MessageEventArgs(message, sender));
}
// 同事类订阅事件
public class EventUser
{
public EventMediator Mediator { get; }
public EventUser(EventMediator mediator)
{
Mediator = mediator;
Mediator.MessageReceived += OnMessageReceived;
}
private void OnMessageReceived(object sender, MessageEventArgs e)
{
if (e.Sender != this)
Console.WriteLine($"收到消息:{e.Message}");
}
public void Send(string message)
=> Mediator.Broadcast(message, this);
}
(3)实战案例:电商订单系统
需求:订单创建需协调库存锁定、支付处理、物流调度。
优势:交互逻辑集中管理,新增模块时只需修改中介者
csharp复制代码
public interface IOrderMediator
{
void LockStock();
void ProcessPayment();
void ScheduleDelivery();
void Rollback();
}
public class OrderSystem : IOrderMediator
{
private InventoryService _inventory;
private PaymentService _payment;
private LogisticsService _logistics;
public void CreateOrder()
{
try
{
LockStock();
ProcessPayment();
ScheduleDelivery();
}
catch
{
Rollback();
}
}
public void LockStock() => _inventory.Lock();
public void ProcessPayment() => _payment.Charge();
public void ScheduleDelivery() => _logistics.Schedule();
public void Rollback()
{
_inventory.Release();
_payment.Refund();
}
}