69

null オブジェクトでAny()を呼び出すと、C# では ArgumentNullException がスローされます。オブジェクトが null の場合、間違いなく「何も」存在せず、おそらく false を返すはずです。

C# がこのように動作するのはなぜですか?

4

8 に答える 8

153

Any()「このボックスにはアイテムが含まれていますか?」

ボックスが空の場合、答えは明らかにノーです。

しかし、そもそもボックスがない場合、質問は意味をなさず、関数は「一体何を話しているのですか?ボックスはありません」と文句を言います。


欠落しているコレクションを空のコレクションのように扱いたい場合は、次の拡張メソッドを使用します。

public static IEnumerable<T> OrEmpty<T>(this IEnumerable<T> sequence)
{
    return sequence ?? Enumerable.Empty<T>();
}

foreachこれは、だけでなく、すべてのLINQメソッドおよびと組み合わせることができます.Any()

于 2012-07-18T09:30:19.833 に答える
55

参照型を扱う場合、null値は「空の」値とは意味的に異なります。

null文字列はと同じではなく、string.Emptyaはと同じでnull IEnumerable<T>はありません Enumerable.Empty<T>(またはそのタイプの他の「空の」列挙可能なもの)。

Any拡張メソッドでない場合は、それを呼び出すとnull結果がになりNullReferenceExceptionます。これ拡張メソッドであるため、(必須ではありませんが)例外をスローすることをお勧めします。これは、nullBOOM!でメソッドを呼び出そうとする際のよく知られたセマンティクスを保持するためです。

于 2012-07-18T09:30:06.590 に答える
5

Any()は拡張メソッドであるため、this実際にはメソッドの最初の引数として渡されます。この状況では、投げることは理解できArgumentNullExceptionます。thisnull

事前に自分でチェックを行うことができます。

bool hasAny = yourData == null ? false : yourData.Any(yourPredicate);
于 2012-07-18T09:29:18.660 に答える
3

Any() は次のような拡張メソッドであるためです。

public static bool Any(this IEnumerable enumerable)
{
    if (enumerable == null)
        throw ArgumentNullException("enumerable");
    ...
}
于 2012-07-18T09:36:20.453 に答える
2

このAnyメソッドは に対して実行され、 Enumerable にIEnumerable項目があるかどうかを通知します。列挙するものを何も与えない場合は、 ArgumentNullException が合理的です。(一致する) 要素のないコレクションは、コレクションがないこととは異なります。

于 2012-07-18T09:28:41.773 に答える
1

他の人がすでに述べたようにAny、シーケンスに要素が含まれているかどうかを確認します。値を渡すことを妨げるものではありませんnull(そもそもバグである可能性があります)。

Enumerableクラス内のすべての拡張メソッドは、 isのArgumentNullException場合にan をスローします。拡張機能を投入することは、実際には良い習慣です。sourcenullArgumentNullExceptions

于 2012-07-18T09:36:33.230 に答える