C#除了业务查询和数据获取,IEnumerable还有其他高频使用场景
这里补充业务查询/数据获取之外的高频场景,覆盖 UI、配置、工具、集合操作、框架扩展、校验、转换等方向,附代码示例,都是实际项目中频繁用到的场景。
一、UI 界面数据绑定(桌面/前端框架高频)
场景说明
WinForm、WPF、ASP.NET、Blazor 等 UI 框架中,控件列表数据源普遍接收 IEnumerable<T>,是界面展示的核心载体。
- 优势:适配所有集合类型,框架内部自动遍历渲染。
1. WinForm DataGridView / ComboBox 绑定
// 模拟数据
var data = new List<string> { "选项1", "选项2", "选项3" };
IEnumerable<string> bindData = data;
// 下拉框绑定
comboBox1.DataSource = bindData;
// 表格绑定
dataGridView1.DataSource = bindData.ToList();
2. WPF 列表控件(ListBox/ItemsControl)
XAML 控件的 ItemsSource 类型本身就是 IEnumerable:
<ListBox ItemsSource="{Binding UserList}" />
后端属性定义:
private IEnumerable<User> _userList;
public IEnumerable<User> UserList
{
get => _userList;
set { _userList = value; OnPropertyChanged(); }
}
二、集合合并、去重、拼接、过滤(通用工具逻辑)
日常对多个序列做组合处理,IEnumerable 配合 LINQ 是标准写法,不属于数据库查询,纯内存运算。
1. 多个序列合并
IEnumerable<int> seq1 = new[] { 1, 2, 3 };
IEnumerable<int> seq2 = new[] { 3, 4, 5 };
// 拼接两个序列
var all = seq1.Concat(seq2);
// 合并并去重
var distinctAll = seq1.Union(seq2);
2. 批量过滤、排除元素
// 排除指定黑名单数据
IEnumerable<string> allTags = new[] { "标签A", "标签B", "标签C" };
IEnumerable<string> blackList = new[] { "标签B" };
var validTags = allTags.Except(blackList);
3. 交集、差集、子集判断(数据比对)
常用于权限、标签、角色、配置项比对:
// 用户拥有的角色
IEnumerable<string> userRoles = new[] { "管理员", "编辑" };
// 接口要求的权限
IEnumerable<string> requireRoles = new[] { "管理员" };
// 判断是否拥有权限(是否存在交集)
bool hasPermission = userRoles.Intersect(requireRoles).Any();
三、批量操作:循环执行任务/调用方法
批量执行逻辑、批量校验、批量下发指令、批量日志输出,用 IEnumerable 承载待处理对象。
1. 批量执行动作
// 待处理任务序列
IEnumerable<TaskItem> tasks = GetLocalTasks();
// 批量执行
foreach (var task in tasks)
{
task.Run();
}
2. 批量参数校验
/// <summary>批量校验字符串非空</summary>
public static bool AllNotEmpty(IEnumerable<string> inputs)
{
return inputs.All(s => !string.IsNullOrWhiteSpace(s));
}
// 调用
var checkItems = new[] { "测试1", "", "测试2" };
bool result = AllNotEmpty(checkItems);
四、配置项、枚举、常量遍历
系统配置、字典映射、枚举遍历、静态常量集合,大量使用 IEnumerable 封装。
1. 枚举遍历
enum Status { 正常, 禁用, 注销 }
// 获取所有枚举项,返回 IEnumerable
IEnumerable<Status> allStatus = Enum.GetValues(typeof(Status)).Cast<Status>();
foreach (var s in allStatus)
{
Console.WriteLine(s);
}
2. 系统配置字典/选项集
// 系统预设选项,只读对外暴露
public static IEnumerable<KeyValuePair<string, string>> SystemOptions
{
get
{
yield return new KeyValuePair<string, string>("0", "关闭");
yield return new KeyValuePair<string, string>("1", "开启");
}
}
五、分页、分片、分批处理(内存数据分页)
不依赖数据库,纯内存集合分页/分片,报表导出、数据分批推送、分块处理都在用。
// 原始序列
IEnumerable<LogInfo> allLogs = GetAllLog();
int pageSize = 20;
// 内存分页
var page1 = allLogs.Skip(0).Take(pageSize);
var page2 = allLogs.Skip(pageSize).Take(pageSize);
大数据分片处理(避免单次处理过多数据)
// 将序列按每 50 条分为一批
var batches = allLogs.Select((item, index) => new { item, index })
.GroupBy(x => x.index / 50)
.Select(g => g.Select(x => x.item));
foreach (var batch in batches)
{
// 分批处理,降低单次压力
ProcessBatchData(batch);
}
六、字符串、文本拆分与遍历
字符串分割、逐字符/逐片段遍历,结合 IEnumerable 做流式处理。
1. 字符遍历
string content = "Hello World";
IEnumerable<char> chars = content; // string 本身实现了 IEnumerable<char>
foreach (var c in chars)
{
Console.Write(c);
}
2. 拆分字符串并过滤
string str = "1,2,,3,4";
IEnumerable<string> parts = str.Split(',')
.Where(s => !string.IsNullOrEmpty(s));
七、日志、监控、事件回调(事件集合/订阅列表)
事件订阅、钩子函数、日志处理器、监控触发器,用 IEnumerable 管理一组回调对象。
// 日志处理器列表
private readonly List<ILogHandler> _logHandlers = new List<ILogHandler>();
// 对外只读暴露处理器
public IEnumerable<ILogHandler> LogHandlers => _logHandlers;
// 触发所有日志处理器
public void WriteLog(string msg)
{
foreach (var handler in LogHandlers)
{
handler.Handle(msg);
}
}
八、参数设计:统一接收多类型入参(通用工具类)
公共工具、扩展方法、帮助类,参数统一声明为 IEnumerable<T>,兼容数组、List、HashSet、LINQ 结果等所有可遍历类型,提升复用性。
示例:通用扩展方法
public static class EnumerableExt
{
// 任意可遍历集合都能调用
public static string JoinToString<T>(this IEnumerable<T> source, string separator = ",")
{
return string.Join(separator, source);
}
}
// 各种类型都能调用
int[] arr = { 1, 2, 3 };
List<int> list = { 4, 5 };
string s1 = arr.JoinToString();
string s2 = list.JoinToString("|");
九、缓存与内存数据管理
缓存列表、内存常驻数据池、临时会话数据,对外用 IEnumerable 保证只读,防止外部篡改缓存。
// 全局内存缓存
private static readonly List<DictItem> _dictCache = new List<DictItem>();
// 只读对外暴露,保护缓存数据
public static IEnumerable<DictItem> DictCache => _dictCache;
十、异步流 / 管道处理(进阶:IAsyncEnumerable)
现代 .NET 中衍生的 IAsyncEnumerable<T>,基于迭代思想,用于异步流式读取:
- 异步读取网络流、消息队列、实时日志、推送数据流
- EF Core 异步分页查询、大文件异步读取
// 异步逐行读取文件
public static async IAsyncEnumerable<string> ReadFileAsync(string path)
{
using var reader = new StreamReader(path);
string line;
while ((line = await reader.ReadLineAsync()) != null)
{
yield return line;
}
// 遍历过程中异步等待,不阻塞线程
await Task.Yield();
}
}
场景汇总&优先级(非数据查询类)
| 场景分类 | 使用频率 | 典型用途 |
|---|---|---|
| UI 控件数据源绑定 | ★★★★★ | WinForm/WPF/Blazor 列表渲染 |
| 集合运算(合并/去重/交集) | ★★★★★ | 内存数据比对、组合、筛选 |
| 批量执行/批量校验 | ★★★★☆ | 任务批量执行、参数校验、指令下发 |
| 枚举/配置项遍历 | ★★★★☆ | 系统下拉选项、枚举解析、静态配置 |
| 内存分页/分片处理 | ★★★★☆ | 报表、分批导出、分块计算 |
| 字符串拆分与遍历 | ★★★☆☆ | 文本解析、字符处理 |
| 事件/回调/处理器集合 | ★★★☆☆ | 日志、钩子、事件订阅 |
| 通用工具方法入参 | ★★★★★ | 公共扩展方法、帮助类 |
| 内存缓存只读暴露 | ★★★☆☆ | 全局字典、常驻数据 |
| 异步流式处理 | ★★★☆☆ | 消息队列、大文件异步读写 |
补充小结
IEnumerable本质是「序列抽象」,不局限于数据库/业务查询,只要是“一组有序元素”,基本都能用它;- 日常编码中:UI绑定、集合运算、批量操作、工具方法 是除数据查询外,最高频的四大场景;
- 设计原则:只要只需要遍历、只读、兼容多容器,就优先选用
IEnumerable<T>。

浙公网安备 33010602011771号