2

流暢な構文で記述されている場合、同じ行内でLINQステートメントを「短絡」する構文シュガーまたは方法はありますか? たとえば、呼び出しnullによって返された場合FirstOrDefault、null を返すことは可能ですか?そうでない場合は、残りのメソッド チェーンを続行しますか?

List<string> testList = new List<string>() { "some", "strings" };
var reversed = testList.FirstOrDefault(x => x == "hello").Reverse();

FirstOrDefault呼び出しは null を返すため、ステートメントは呼び出しで をスローしArgumentNullExceptionますReverseReverseその時点でデフォルト値が返されたので、呼び出しの前に停止する方法はありますか?

(クエリを別の行に分割してdefault(T)前にチェックできることは知っていますがReverse、単純なケースでは条件演算子(?:)を使用できますが、より長い/より複雑なチェーンの特定の機能が欠けているかどうか知りたいです)

編集 - 明確にするために、これはアイデアを示すための単なる例であり、実際のコードの一部ではありません。行を分割してチェックを行う方がパフォーマンスが向上するため、例外がスローされるのを避けたいと思います。

4

3 に答える 3

4

FirstOrDefaultセットを単一のアイテムに解決してそのアイテムを操作したいが、そのアイテムがセット内に見つからない可能性がある状況を適切に処理したい場合は、次のように最後まで遅延させることができます:

var reversed = testList
    .Where(x => x == "hello")
    .Select(x => x.Reverse())
    .FirstOrDefault();

または同等に

var reversed = testList
    .Where(x => x == "hello")
    .Select(Enumerable.Reverse)
    .FirstOrDefault();

nullこれは、メソッドで指定された条件を満たすアイテムがリストにない場合に返されますWhere。ここでのパフォーマンスの違いは、せいぜい無視できる程度です。testList最初の要素が見つかるとすぐに結果が返されるため、元のコードをループする必要はありません。

于 2013-08-14T15:44:33.477 に答える
2

Maybe モナドの C# バージョンを探しているようです。

public static class MaybeMonadExtensions
{
    public static TResult GetIfNotNull<TInput, TResult>(this TInput o, Func<TInput, TResult> evaluator)
        where TResult : class
        where TInput : class
    {
        return o == null ? null : evaluator(o);
    }
}

これを使用して、次のように記述できます。

var reversed = testList.FirstOrDefault(x => x == "hello").GetIfNotNull(s => s.Reverse());

リストに「hello」という単語が含まれていない場合は、null が出力されます。

于 2013-08-14T15:51:14.673 に答える
2

はい、FirstOrDefault の代わりに First を使用してください。以前に例外をスローします。

于 2013-08-14T15:40:35.277 に答える