【问题标题】:return results without iteration inside of a foreach在 foreach 内不进行迭代就返回结果
【发布时间】:2019-07-16 23:30:04
【问题描述】:

我需要通过从表存储中加载连接信息来创建一个ConnectionInfo 对象:

    public static async Task<ConnectionInfo> LoadConnection(CloudTable cloudTable, string container)
    {
        var filter = TableQuery.GenerateFilterCondition("container", QueryComparisons.Equal, container);

        foreach (var entity in await cloudTable.ExecuteQuerySegmentedAsync(new TableQuery<SftpServerConnectionsModel>().Where(filter), null))
        {
            return new ConnectionInfo(entity.uri, entity.user, new AuthenticationMethod[]{
            new PasswordAuthenticationMethod(entity.user,entity.password)});
        }
    }

如何创建 ConnectionInfo 对象并立即返回,而不是继续在 foreach 循环内进行迭代?

我们可以完全绕过 foreach 吗?我总是期待 1 且只有 1 个结果。

【问题讨论】:

  • 这不是你的代码现在所做的(即当你点击return时返回)?是什么让你认为不是?我怀疑您的真正问题是它无法编译 - 在这种情况下,您可能需要在 foreach 之后返回 null (以防从未进入循环)。或者使用FirstOrDefault 而不是foreach
  • 提示 - 如果您的代码无法编译,请告诉我们编译器错误是什么

标签: c# azure-table-storage


【解决方案1】:

由于您总是期望 1 个且只有 1 个结果,因此您可以对 ExecuteQuerySegmentedAsync 的结果执行 .Single(),而不是使用 foreach 对其进行迭代:

public static async Task<ConnectionInfo> LoadConnection(CloudTable cloudTable, string container) 
{ 
    var filter = TableQuery.GenerateFilterCondition("container", QueryComparisons.Equal, container);

    var entity = (await cloudTable.ExecuteQuerySegmentedAsync(new TableQuery<SftpServerConnectionsModel>().Where(filter), null)).Single();

    return new ConnectionInfo(entity.uri, entity.user, new AuthenticationMethod[] { new PasswordAuthenticationMethod(entity.user,entity.password)});
}

您当前拥有的foreach 方法实际上将返回迭代的第一项,之后不会继续迭代任何其他结果。但是,像这样执行.Single() 会使该方法更清楚地了解它的预期作用。

【讨论】:

    【解决方案2】:

    基于“我总是期待 1 且只有 1 个结果”。为什么首先要循环?

    如果必须发生循环,则表示第一个循环没有设置connectionInfo,这意味着您需要找出它何时设置或实例化,然后停止循环。你最好的选择是检查实体变量

    这正是 break 的用途。在循环之外声明 connectionInfo,然后一旦分配就退出它。

    ConnectionInfo connectionInfo = null;
    foreach (var entity in await cloudTable.ExecuteQuerySegmentedAsync(new TableQuery<SftpServerConnectionsModel>().Where(filter), null))
        {
            connectionInfo = new ConnectionInfo(entity.uri, entity.user, new AuthenticationMethod[]{
            new PasswordAuthenticationMethod(entity.user,entity.password)});
            //If entity is not null break out
            break;
        }
    

    另一个更漂亮的解决方案是使用 while 循环,while 与整个 await 变量.Any(),然后做同样的检查

    【讨论】:

      【解决方案3】:

      如果只期望 1 个结果,则明确请求它

      例如

      public static async Task<ConnectionInfo> LoadConnection(CloudTable cloudTable, string container) {
          var filter = TableQuery.GenerateFilterCondition("container", QueryComparisons.Equal, container);
          var query = new TableQuery<SftpServerConnectionsModel>().Where(filter);
          var querySegment = await cloudTable.ExecuteQuerySegmentedAsync(query, null);
          var entity = querySegment.FirstOrDefault();
          if(entity != null) {
              return new ConnectionInfo(entity.uri, entity.user, new AuthenticationMethod[]{
              new PasswordAuthenticationMethod(entity.user,entity.password)});
          }
          return default(ConnectionInfo);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-12-18
        • 2019-12-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-07-06
        • 1970-01-01
        相关资源
        最近更新 更多