簡體   English   中英

C# 在 Enumerable.All 擴展中使用帶有 return bool 的異步 lambda 表達式

[英]C# use async lambda expression with return bool in Enumerable.All extension

我有以下async方法

private async Task<bool> HasPolicy(AuthorizationFilterContext context, string policy)
{
    var authorized = await _authorization.AuthorizeAsync(context.HttpContext.User, policy);
    return authorized.Succeeded;
}

我想在Enumerable.AllEnumerable.Any擴展中使用它

var result1 = IsAndPolicy
    ? policys.All(async x => await HasPolicy(context, x))
    : policys.Any(async x => await HasPolicy(context, x));

但是上面的代碼得到以下錯誤

錯誤 CS4010 無法將異步 lambda 表達式轉換為委托類型“Func<string, bool>”。 異步 lambda 表達式可能返回 void、Task 或 Task,它們都不能轉換為 'Func<string, bool>'。

一種方法是投影IEnumerable<Task<bool>>

var results = await Task.WhenAll(policys.Select(x => HasPolicy(context, x)));

var result1 = IsAndPolicy 
   ? results.All(x => x)                
   : results.Any(x => x);

這種方法的問題在於,您正在處理所有可能不必要的項目。

Michael Randall 的答案產生了正確的邏輯結果,但必須評估所有策略,即使在這兩種情況下,評估都可能因All的第一個false結果或Any的第一個true結果而短路。

這可以通過將任務轉換為IAsyncenumerable<T>並使用System.Linq.Async來避免:

var resultTasks=policies.ToAsyncEnumerable()
                        .Select(async x => await HasPolicy(context, x));

var result1 = await (IsAndPolicy 
                       ? resultTasks.AllAsync(x => x)                
                       : resultTasks.AnyAsync(x => x));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM