[英]Is there way to simplify a LINQ statement using if-else statement in c#
我有一個有效的 LINQ 表達式,但我想讓它更簡單、更清晰。
var tryCatchTerminator = true;
return tryCatchTerminator
? from varKeyword in MatchToken(SyntaxKind.VarKeyword)
from declarations in ParseVarDeclarationClause.AtLeastOnceDelimitedBy(MatchToken(SyntaxKind.Comma))
from terminator in MatchToken(SyntaxKind.SemiColon).OptionalOrDefault()
select (StatementSyntax) new VarDeclarationStatement(varKeyword, declarations, terminator)
: from varKeyword in MatchToken(SyntaxKind.VarKeyword)
from declarations in ParseVarDeclarationClause.AtLeastOnceDelimitedBy(MatchToken(SyntaxKind.Comma))
select (StatementSyntax) new VarDeclarationStatement(varKeyword, declarations, Token<SyntaxKind>.Empty);
我在互聯網上尋找某種方式在 LINQ 表達式中包含 if 語句,如果滿足某些條件,我可以停止並返回一個對象……或者如果不滿足條件,則繼續執行另一個查詢。
也許這很明顯,但我真的一無所知。
在我看來,這應該適合你:
return
from varKeyword in MatchToken(SyntaxKind.VarKeyword)
from declarations in ParseVarDeclarationClause.AtLeastOnceDelimitedBy(MatchToken(SyntaxKind.Comma))
from terminator in tryCatchTerminator ? MatchToken(SyntaxKind.SemiColon).OptionalOrDefault() : new[] { Token<SyntaxKind>.Empty }
select (StatementSyntax)new VarDeclarationStatement(varKeyword, declarations, terminator);
如果tryCatchTerminator
為false
,它工作的關鍵就是給from terminator
表達式一個單元素數組以返回空標記。
我最終創建了一個直通解析器..它不消耗令牌並返回一個空令牌。
private static TokenListParser<SyntaxKind, StatementSyntax> ParseExpressionStatement(
bool lookForTerminator)
{
return from expression in ParsePrefixExpression.Or(ParseCallExpression())
from terminator in lookForTerminator
? MatchToken(SyntaxKind.SemiColon).OptionalOrDefault()
: PassThrough<SynaxKind>()
select (StatementSyntax) new ExpressionStatementSyntax(expression, terminator);
}
private static TokenListParser<T, Token<T>> PassThrough<T>(Token<T> empty)
{
return input =>
{
var output = input.ConsumeToken();
return TokenListParserResult.Value(Token<T>.Empty, output.Location, output.Location);
};
}
很難根據您的代碼示例判斷這是否有效,但我不明白為什么您無法檢查 LINQ 查詢中的條件:
return from varKeyword in MatchToken(SyntaxKind.VarKeyword)
from declarations in ParseVarDeclarationClause.AtLeastOnceDelimitedBy(MatchToken(SyntaxKind.Comma))
from terminator in MatchToken(SyntaxKind.SemiColon).DefaultIfEmpty()
select (StatementSyntax)new VarDeclarationStatement(varKeyword, declarations, tryCatchTerminator ? terminator : Token<SyntaxKind>.Empty); // check here and pass correct value to VarDeclarationStatement
如果我正確理解您的問題,那么不,一旦查詢開始,就沒有(內置)方法可以“停止”查詢。 如果您想在枚舉期間添加等於取消謂詞的內容,這表明枚舉是否應該繼續,最簡單的方法是創建自定義迭代器。 這樣的實現可能如下所示:
public sealed class BreakingEnumerable<T> : IEnumerable<T>
{
private readonly IEnumerable<T> _query;
private readonly Predicate<T> _continuePredicate;
public BreakingEnumerable(IEnumerable<T> query, Predicate<T> predicate)
{
_query = query ?? throw new ArgumentNullException(nameof(query));
_continuePredicate = predicate ?? throw new ArgumentNullException(nameof(predicate));
}
public IEnumerator<T> GetEnumerator()
{
foreach (var item in _query)
{
if (_continuePredicate(item))
{
yield return item;
}
else
{
yield break;
}
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
當然,您希望將這部分作為查詢的一部分,因此您可能需要一個擴展方法類來將查詢轉換為這個自定義可枚舉:
public static class BreakingEnumerableExtensions {
public static BreakingEnumerable<T> WithTerminationClause<T>(
this IEnumerable<T> query,
Predicate<T> breakCondition)
{
return new BreakingEnumerable<T>(query, breakCondition);
}
}
這是實際用法:
static void Main(string[] args)
{
var enumerable = Enumerable.Range(1, 100);
var array = enumerable.WithTerminationClause(i => i > 100).ToArray();
Console.WriteLine($"Enumerable with termination clause array length: {array.Length}");
array = enumerable.Where(i => i < 20).WithTerminationClause(i => i % 2 == 0)
.ToArray();
Console.WriteLine($"Enumerable with termination clause length: {array.Length}");
}
結果如下:
Enumerable with termination clause array length: 0
Enumerable with termination clause length: 9
這可以鏈接以產生一些小的優化:
// Outputs: `Query results: [100, 200, 300]`
var enumerable = Enumerable.Range(1, 100);
var sub = enumerable.WithTerminationClause(i => i <= 3)
.Select(i => i * 100);
Console.WriteLine("Query results: [{0}]", string.Join(", ", sub));
唯一的“障礙”是您永遠不會想要使用它,除非您可以保證某種形式的排序:例如,所有數字都以有序的順序出現。 如果您沒有強制執行此保證,則您的程序可能會產生不正確的結果。
希望這可以幫助!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.