如何为多模型映射场景创建通用C#异步方法?
通用列表映射方法实现方案
完全可以通过泛型结合委托的方式,把这类重复的异步获取+列表对象映射逻辑统一封装,不用为每个模型写重复代码。
核心思路
把两个变化的部分抽成参数:
- 异步获取源列表的方法(比如
GetFirstMethod、GetSecondMethod) - 单个源对象到目标对象的映射逻辑(比如
Result1转Target1的规则)
剩下的“调用异步方法→获取源列表→遍历映射成目标列表”的固定流程,用泛型方法统一实现。
代码示例
假设我们有如下基础模型和方法:
// 源模型示例 public class Result1 { public int Id { get; set; } public string Name { get; set; } } public class Result2 { public Guid Uid { get; set; } public string Title { get; set; } } // 目标模型示例 public class Target1 { public int ItemId { get; set; } public string ItemName { get; set; } } public class Target2 { public Guid ItemUid { get; set; } public string ItemTitle { get; set; } } // 现有异步方法示例 public Task<List<Result1>> GetFirstMethod() { /* 实际获取反序列化后的Result1列表逻辑 */ } public Task<List<Result2>> GetSecondMethod() { /* 实际获取反序列化后的Result2列表逻辑 */ }
接下来写通用方法:
/// <summary> /// 通用异步获取+列表映射方法 /// </summary> /// <typeparam name="TSource">源模型类型</typeparam> /// <typeparam name="TTarget">目标模型类型</typeparam> /// <param name="getListFunc">异步获取源列表的方法</param> /// <param name="mapFunc">单个源对象到目标对象的映射逻辑</param> /// <returns>映射后的目标模型列表</returns> public async Task<List<TTarget>> GetAndMapListAsync<TSource, TTarget>( Func<Task<List<TSource>>> getListFunc, Func<TSource, TTarget> mapFunc) { // 1. 调用异步方法获取源列表 var sourceList = await getListFunc(); // 2. 遍历映射成目标列表(空列表直接返回空,避免空引用) return sourceList?.Select(mapFunc).ToList() ?? new List<TTarget>(); }
使用示例
调用这个通用方法处理不同模型:
// 处理Result1→Target1 var targetList1 = await GetAndMapListAsync<Result1, Target1>( GetFirstMethod, result => new Target1 { ItemId = result.Id, ItemName = result.Name }); // 处理Result2→Target2 var targetList2 = await GetAndMapListAsync<Result2, Target2>( GetSecondMethod, result => new Target2 { ItemUid = result.Uid, ItemTitle = result.Title });
扩展优化
如果映射逻辑比较复杂,也可以把mapFunc换成更灵活的实现,比如结合AutoMapper的IMapper.Map<TTarget>(TSource):
// 假设已经配置好AutoMapper映射规则 private readonly IMapper _mapper; // 用AutoMapper简化映射 var targetList1 = await GetAndMapListAsync<Result1, Target1>( GetFirstMethod, _mapper.Map<Target1>);
这种方式完全复用了固定流程,不管新增多少种Result模型和对应的异步方法,只要传入对应的获取方法和映射逻辑即可,不用重复写列表处理的代码。
内容的提问来源于stack exchange,提问作者Ya YA
相关产品推荐
相关产品推荐

