[英]Enumerable.Where(predicate) vs. Enumerable.All(predicate)
[英]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.All
和Enumerable.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.