// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。 // // 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。 // // 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任! namespace Admin.NET.Core; /// /// 队列扩展方法 /// public static class QueueExtensions { /// /// 批量入队 /// /// 队列元素类型 /// 队列实例 /// 要入队的元素集合 /// 队列或元素集合为空时抛出 public static void EnqueueRange(this Queue queue, IEnumerable items) { ArgumentNullException.ThrowIfNull(queue); ArgumentNullException.ThrowIfNull(items); foreach (var item in items) { queue.Enqueue(item); } } /// /// 批量出队 /// /// 队列元素类型 /// 队列实例 /// 要出队的元素数量 /// 出队的元素集合 /// 队列为空时抛出 /// 数量小于0或大于队列长度时抛出 public static IEnumerable DequeueRange(this Queue queue, int count) { ArgumentNullException.ThrowIfNull(queue); if (count < 0) { throw new ArgumentOutOfRangeException(nameof(count), "数量不能小于0"); } if (count > queue.Count) { throw new ArgumentOutOfRangeException(nameof(count), "数量不能大于队列长度"); } var result = new List(count); for (var i = 0; i < count; i++) { result.Add(queue.Dequeue()); } return result; } /// /// 尝试出队多个元素 /// /// 队列元素类型 /// 队列实例 /// 要出队的元素数量 /// 出队的元素集合 /// 是否成功出队指定数量的元素 public static bool TryDequeueRange(this Queue queue, int count, out IEnumerable items) { items = []; if (count < 0 || count > queue.Count) { return false; } var result = new List(count); for (var i = 0; i < count; i++) { if (queue.TryDequeue(out var item)) { result.Add(item); } else { // 恢复已出队的元素 foreach (var restoredItem in result.AsEnumerable().Reverse()) { var tempQueue = new Queue(); tempQueue.Enqueue(restoredItem); while (queue.Count > 0) { tempQueue.Enqueue(queue.Dequeue()); } while (tempQueue.Count > 0) { queue.Enqueue(tempQueue.Dequeue()); } } return false; } } items = result; return true; } /// /// 清空队列并返回所有元素 /// /// 队列元素类型 /// 队列实例 /// 队列中的所有元素 /// 队列为空时抛出 public static IEnumerable DrainToList(this Queue queue) { ArgumentNullException.ThrowIfNull(queue); var result = new List(queue.Count); while (queue.Count > 0) { result.Add(queue.Dequeue()); } return result; } /// /// 安全地查看队列头部元素 /// /// 队列元素类型 /// 队列实例 /// 队列头部元素 /// 是否成功查看 public static bool TryPeek(this Queue queue, out T? item) { item = default; if (queue.Count == 0) { return false; } item = queue.Peek(); return true; } /// /// 检查队列是否为空 /// /// 队列元素类型 /// 队列实例 /// 队列是否为空 public static bool IsEmpty(this Queue queue) { return queue?.Count == 0; } /// /// 检查队列是否不为空 /// /// 队列元素类型 /// 队列实例 /// 队列是否不为空 public static bool IsNotEmpty(this Queue queue) { return queue?.Count > 0; } /// /// 将队列转换为数组 /// /// 队列元素类型 /// 队列实例 /// 包含队列所有元素的数组 /// 队列为空时抛出 public static T[] ToArrayPreserveOrder(this Queue queue) { ArgumentNullException.ThrowIfNull(queue); return [.. queue]; } /// /// 复制队列 /// /// 队列元素类型 /// 原队列 /// 复制的新队列 /// 队列为空时抛出 public static Queue Clone(this Queue queue) { ArgumentNullException.ThrowIfNull(queue); return new Queue(queue); } /// /// 查找队列中是否包含满足条件的元素 /// /// 队列元素类型 /// 队列实例 /// 匹配条件 /// 是否包含满足条件的元素 /// 队列或条件为空时抛出 public static bool Contains(this Queue queue, Func predicate) { ArgumentNullException.ThrowIfNull(queue); ArgumentNullException.ThrowIfNull(predicate); return queue.Any(predicate); } /// /// 统计队列中满足条件的元素数量 /// /// 队列元素类型 /// 队列实例 /// 匹配条件 /// 满足条件的元素数量 /// 队列或条件为空时抛出 public static int Count(this Queue queue, Func predicate) { ArgumentNullException.ThrowIfNull(queue); ArgumentNullException.ThrowIfNull(predicate); return queue.Count(predicate); } /// /// 对队列中的每个元素执行指定操作 /// /// 队列元素类型 /// 队列实例 /// 要执行的操作 /// 队列或操作为空时抛出 public static void ForEach(this Queue queue, Action action) { ArgumentNullException.ThrowIfNull(queue); ArgumentNullException.ThrowIfNull(action); foreach (var item in queue) { action(item); } } /// /// 对队列中的每个元素执行指定操作(带索引) /// /// 队列元素类型 /// 队列实例 /// 要执行的操作,参数为元素和索引 /// 队列或操作为空时抛出 public static void ForEach(this Queue queue, Action action) { ArgumentNullException.ThrowIfNull(queue); ArgumentNullException.ThrowIfNull(action); var index = 0; foreach (var item in queue) { action(item, index++); } } /// /// 创建一个新队列,包含满足条件的元素 /// /// 队列元素类型 /// 原队列 /// 筛选条件 /// 包含满足条件元素的新队列 /// 队列或条件为空时抛出 public static Queue Where(this Queue queue, Func predicate) { ArgumentNullException.ThrowIfNull(queue); ArgumentNullException.ThrowIfNull(predicate); var result = new Queue(); foreach (var item in queue.Where(predicate)) { result.Enqueue(item); } return result; } /// /// 创建一个新队列,包含转换后的元素 /// /// 原队列元素类型 /// 目标队列元素类型 /// 原队列 /// 转换函数 /// 包含转换后元素的新队列 /// 队列或转换函数为空时抛出 public static Queue Select(this Queue queue, Func selector) { ArgumentNullException.ThrowIfNull(queue); ArgumentNullException.ThrowIfNull(selector); var result = new Queue(); foreach (var item in queue.Select(selector)) { result.Enqueue(item); } return result; } /// /// 限制队列的最大长度,超出时移除最旧的元素 /// /// 队列元素类型 /// 队列实例 /// 最大长度 /// 队列为空时抛出 /// 最大长度小于0时抛出 public static void LimitSize(this Queue queue, int maxSize) { ArgumentNullException.ThrowIfNull(queue); if (maxSize < 0) { throw new ArgumentOutOfRangeException(nameof(maxSize), "最大长度不能小于0"); } while (queue.Count > maxSize) { queue.Dequeue(); } } /// /// 安全地入队元素,如果队列已满则移除最旧的元素 /// /// 队列元素类型 /// 队列实例 /// 要入队的元素 /// 队列最大长度 /// 被移除的元素(如果有) /// 队列为空时抛出 /// 最大长度小于1时抛出 public static T? EnqueueWithLimit(this Queue queue, T item, int maxSize) { ArgumentNullException.ThrowIfNull(queue); if (maxSize < 1) { throw new ArgumentOutOfRangeException(nameof(maxSize), "最大长度不能小于1"); } T? removedItem = default; if (queue.Count >= maxSize) { removedItem = queue.Dequeue(); } queue.Enqueue(item); return removedItem; } }