泛型方法中从object[]获取List<T>报错,分页API聚合场景求解
解决分页API结果聚合时JObject转实体类的问题
问题根源很明确:你的PaginatedResult类中results字段定义为object[],当API返回的JSON被反序列化时,Json.NET无法自动将嵌套的实体对象直接转成T类型,而是会将它们解析为JObject实例——这就是直接强转时抛出类型转换错误的原因。
下面给你两种可行的解决方案,根据你是否能修改PaginatedResult类来选择:
方案1:将PaginatedResult改为泛型类(推荐)
如果有权限修改PaginatedResult的定义,直接把它改成泛型类是最优雅的解决方式,从根源避免类型转换问题:
public class PaginatedResult<T> { public int TotalItems { get; set; } public int CurrentPage { get; set; } public int PageSize { get; set; } public T[] Results { get; set; } // 也可以用List<T> }
之后调用API并反序列化时,直接指定泛型参数:
var page = JsonConvert.DeserializeObject<PaginatedResult<YourEntity>>(responseContent);
此时page.Results已经是强类型的YourEntity[],聚合分页结果时直接AddRange即可,完全不需要额外转换。
方案2:无法修改PaginatedResult时的转换处理
如果PaginatedResult是第三方类或者无法修改,就需要手动将数组中的JObject转换为目标类型T。利用Json.NET的JObject.ToObject<T>()方法就能完成映射:
public async Task<List<T>> AggregateAllPages<T>(Func<int, Task<PaginatedResult>> getPage) { var fullList = new List<T>(); int pageNum = 1; PaginatedResult currentPage; do { currentPage = await getPage(pageNum); foreach (var item in currentPage.Results) { // 处理JObject类型的元素 if (item is JObject jobj) { var entity = jobj.ToObject<T>(); fullList.Add(entity); } // 兼容特殊情况:如果元素已经是T类型(比如某些分页返回的是实体而非JObject) else if (item is T entity) { fullList.Add(entity); } } pageNum++; } while (currentPage.Results.Length > 0 && pageNum <= (currentPage.TotalItems / currentPage.PageSize) + 1); return fullList; }
关于实体类继承PaginatedResult的疑问
这个思路完全不可行,逻辑上就不成立:PaginatedResult是分页结果的容器,包含分页元数据(总条数、页码等)和结果列表;而你的实体类是列表中的单个数据项。让实体类继承容器类会把分页信息和业务数据混在一起,违背单一职责原则,后续维护会出大问题,绝对不要这么做。
内容的提问来源于stack exchange,提问作者max tuerpe
相关产品推荐
相关产品推荐

