You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#/.NET中能否访问Func<>传入的方法参数?分页API查询方案

分页API迭代查找指定对象的实现问题与解决方案

我需要实现一个方法,能够迭代调用支持分页的RESTful API接口,直到找到指定的JSON对象。以下是相关代码示例及遇到的问题:

现有API客户端代码(ApiClient.cs)

// 调用REST API的示例方法
public async Task<ICollection<PetsApiResonse>> GetPets(string searchQuery, int skip = 0, int take = 20, bool includeAdopted = false)
{
  // 发起HTTP请求的逻辑,例如 'GET {baseUri}/pets'
}

public async Task<ICollection<EmployeesApiResonse>> GetEmployees(string searchQuery, int skip = 0, int take = 20)
{
  // 发起HTTP请求的逻辑,例如 'GET {baseUri}/employees'
}

当前无法正常工作的分页查找方法(RequestHandler.cs)

// 目前无法正常工作的、接收Func<>的示例方法
public static async Task<T> PagedLookupAsync<T>(Func<Task<PetShopApiResponse<ICollection<T>>>> getResponse, string propertyToCompare, object valueToCompare, int maxIterations = 10)
{
  Type type = typeof(T);
  PropertyInfo propertyInfo = type.GetProperty(propertyToCompare);
  ICollection<T> response;
  do
  {
    // 此处需要修改'skip'参数值,以获取API的不同分页结果
    response = await getResponse();
    maxIterations--;
  }
  while (maxIterations >= 0 && !response.Any(o => valueToCompare.Equals(propertyInfo.GetValue(o))));

  return response.FirstOrDefault(o => valueToCompare.Equals(propertyInfo.GetValue(o)));
}

NUnit测试用例示例

var petIdToFind = "123";

var response = RequestHandler.PagedLookupAsync(ApiClient.GetPetsAsync("sparky", take: 50), nameof(PetsApiResonse.Id), petIdToFind);

response.Result.Should().NotBeNull();
response.Result.Id.Should().BeEquivalentTo(petIdToFind);

我的目标是测试记录是否存在且可被搜索,但搜索结果不一定在第一页,导致测试不稳定。我希望集中化该逻辑而非在每个测试用例中编写循环,因此有两个问题:

  1. 能否使用反射访问传入Func<>的方法的参数?我需要修改skip参数,但目前似乎只能访问Func<>自身的参数,无法访问其内部方法的参数。
  2. 如果上述方案不可行,有没有更好的集中化逻辑实现方式?

补充说明:

  • API请求方法由OpenApi规范生成,我无法直接修改,但可以扩展。
  • 参数命名固定:用skip表示分页起始位置,take表示分页大小。

更新:最终解决方案

基于建议调整后,移除了反射,实现如下:

修改后的分页查找方法(RequestHandler.cs)

public static async Task<T> PagedLookupAsync<T>(
  Func<(int SkipState, int TakeState), Task<PetShopApiResponse<ICollection<T>>>> getResponse,
  Func<T, bool> lookupFunction,
  int maxIterations = 10)
{
  int skip = 0;
  int take = 20;
  ICollection<T> response;
  bool isFound = false;
  do
  {
    response = await getResponse((skip, take));

    isFound = response.Any(o => lookupFunction(o));
    skip += take;
    maxIterations--;
  }
  while (maxIterations >= 0 && !isFound);

  return response.FirstOrDefault(o => lookupFunction(o));
}

调用示例

var response = RequestHandler.PagedLookupAsync((s, t) =>
  ApiClient.GetPetsAsync("sparky", skip: s, take: t),
  (lookup) => lookup.Id == petIdToFind);

内容的提问来源于stack exchange,提问作者officeSpacePirate

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 05:16:01