When calling Any() on a null object, it throws an ArgumentNullException in C#. If the object is null, there definitely aren't 'any', and it should probably return false.
当在null对象上调用任何()时,它会在c#中抛出一个ArgumentNullException。如果对象为空,则肯定不存在'any',并且它可能返回false。
Why does C# behave this way?
c#为什么这样做?
7 个解决方案
#1
25
When dealing with reference types, a null
value is semantically different from an "empty" value.
在处理引用类型时,空值与“空”值在语义上是不同的。
A null
string is not the same as string.Empty
, and a null
IEnumerable<T>
is not the same as Enumerable.Empty<T>
(or any other "empty" enumerable of that type).
空字符串不同于字符串。空的IEnumerable,空的IEnumerable
If Any
were not an extension method, calling it on null
would result in NullReferenceException
. Since it is an extension method, throwing some exception (although not necessary) is a good idea because it preserves the well-known semantics of trying to call a method on null
: BOOM!
如果Any不是扩展方法,那么在null上调用它将导致NullReferenceException。由于它是一个扩展方法,抛出一些异常(虽然不是必需的)是一个好主意,因为它保留了尝试在null: BOOM上调用一个方法的众所周知的语义。
#2
94
Any()
is asking: "Does this box contain any items?"
Any()是问:“这个盒子里有什么东西吗?”
If the box is empty, the answer is clearly no.
如果盒子是空的,答案显然是否定的。
But if there is no box in the first place, then the question makes no sense, and the function complains: "What the hell are you talking about? There is no box."
但是如果一开始就没有盒子,那么这个问题就没有意义了,函数会抱怨:“你到底在说什么?”没有盒子。”
#3
4
Any()
is an extension method, so this
is actually passed as the first argument to the method. In this situation, it's understandable for it to throw ArgumentNullException
is this
is null
.
Any()是一个扩展方法,因此它实际上是作为方法的第一个参数传递的。在这种情况下,抛出ArgumentNullException是null是可以理解的。
You can perform the check yourself beforehand:
你可以自己先检查:
bool hasAny = yourData == null ? false : yourData.Any(yourPredicate);
#4
4
With modern C#, you can easily handle the OP's scenario with a simple check like this:
使用现代c#,您可以轻松地处理OP的场景,只需进行如下简单的检查:
List<string> foo = null;
if (foo?.Any() ?? false)
{
DoStuff();
}
This is kinda like a lame AnyOrDefault(bool default)
implementation that the OP is expecting the Any()
extension method to do.
这有点像一个跛脚的AnyOrDefault(bool default)实现,OP期望Any()扩展方法实现这个实现。
You could easily make this into an extension like this:
你可以很容易地把它扩展成如下:
public static bool AnyOrDefault<T>(this IEnumerable<T> source)
{
return (source?.Any() ?? false);
}
Honestly, I don't really like the name AnyOrDefault
for this since it won't ever make sense to pass in a default value (a default of true would probably be pretty mean to people reading code later).
老实说,我不太喜欢这个名称或默认值,因为传递一个默认值是没有意义的(默认值为true可能对以后阅读代码的人来说很不好)。
#5
1
The Any
method runs against an IEnumerable
and tells you whether there are any items in the Enumerable. If you don't give it anything to enumerate then an ArgumentNullException is reasonable: a collection with no (matching) elements is different to no collecion.
Any方法运行于一个IEnumerable,它告诉您在Enumerable中是否有任何项。如果不需要枚举,那么ArgumentNullException是合理的:没有(匹配)元素的集合与没有collecion的集合是不同的。
#6
1
Because Any() it is a extension method like this:
因为Any()是这样的扩展方法:
public static bool Any(this IEnumerable enumerable)
{
if (enumerable == null)
throw ArgumentNullException("enumerable");
...
}
#7
1
As others have already mentioned, Any
checks whether or not a sequence contains elements. It does not prevent you from passing null
values(what might the bug in the first place).
正如其他人已经提到的,任何检查序列是否包含元素。它不会阻止您传递空值(错误一开始可能是什么)。
Every extension method in Enumerable
class throws an an ArgumentNullException
if the source
is null
. Throwing ArgumentNullExceptions
in extensions actually is good practise.
如果源为空,那么可枚举类中的每个扩展方法都会抛出一个ArgumentNullException。在扩展中抛出ArgumentNullExceptions实际上是一个很好的练习。
#1
25
When dealing with reference types, a null
value is semantically different from an "empty" value.
在处理引用类型时,空值与“空”值在语义上是不同的。
A null
string is not the same as string.Empty
, and a null
IEnumerable<T>
is not the same as Enumerable.Empty<T>
(or any other "empty" enumerable of that type).
空字符串不同于字符串。空的IEnumerable,空的IEnumerable
If Any
were not an extension method, calling it on null
would result in NullReferenceException
. Since it is an extension method, throwing some exception (although not necessary) is a good idea because it preserves the well-known semantics of trying to call a method on null
: BOOM!
如果Any不是扩展方法,那么在null上调用它将导致NullReferenceException。由于它是一个扩展方法,抛出一些异常(虽然不是必需的)是一个好主意,因为它保留了尝试在null: BOOM上调用一个方法的众所周知的语义。
#2
94
Any()
is asking: "Does this box contain any items?"
Any()是问:“这个盒子里有什么东西吗?”
If the box is empty, the answer is clearly no.
如果盒子是空的,答案显然是否定的。
But if there is no box in the first place, then the question makes no sense, and the function complains: "What the hell are you talking about? There is no box."
但是如果一开始就没有盒子,那么这个问题就没有意义了,函数会抱怨:“你到底在说什么?”没有盒子。”
#3
4
Any()
is an extension method, so this
is actually passed as the first argument to the method. In this situation, it's understandable for it to throw ArgumentNullException
is this
is null
.
Any()是一个扩展方法,因此它实际上是作为方法的第一个参数传递的。在这种情况下,抛出ArgumentNullException是null是可以理解的。
You can perform the check yourself beforehand:
你可以自己先检查:
bool hasAny = yourData == null ? false : yourData.Any(yourPredicate);
#4
4
With modern C#, you can easily handle the OP's scenario with a simple check like this:
使用现代c#,您可以轻松地处理OP的场景,只需进行如下简单的检查:
List<string> foo = null;
if (foo?.Any() ?? false)
{
DoStuff();
}
This is kinda like a lame AnyOrDefault(bool default)
implementation that the OP is expecting the Any()
extension method to do.
这有点像一个跛脚的AnyOrDefault(bool default)实现,OP期望Any()扩展方法实现这个实现。
You could easily make this into an extension like this:
你可以很容易地把它扩展成如下:
public static bool AnyOrDefault<T>(this IEnumerable<T> source)
{
return (source?.Any() ?? false);
}
Honestly, I don't really like the name AnyOrDefault
for this since it won't ever make sense to pass in a default value (a default of true would probably be pretty mean to people reading code later).
老实说,我不太喜欢这个名称或默认值,因为传递一个默认值是没有意义的(默认值为true可能对以后阅读代码的人来说很不好)。
#5
1
The Any
method runs against an IEnumerable
and tells you whether there are any items in the Enumerable. If you don't give it anything to enumerate then an ArgumentNullException is reasonable: a collection with no (matching) elements is different to no collecion.
Any方法运行于一个IEnumerable,它告诉您在Enumerable中是否有任何项。如果不需要枚举,那么ArgumentNullException是合理的:没有(匹配)元素的集合与没有collecion的集合是不同的。
#6
1
Because Any() it is a extension method like this:
因为Any()是这样的扩展方法:
public static bool Any(this IEnumerable enumerable)
{
if (enumerable == null)
throw ArgumentNullException("enumerable");
...
}
#7
1
As others have already mentioned, Any
checks whether or not a sequence contains elements. It does not prevent you from passing null
values(what might the bug in the first place).
正如其他人已经提到的,任何检查序列是否包含元素。它不会阻止您传递空值(错误一开始可能是什么)。
Every extension method in Enumerable
class throws an an ArgumentNullException
if the source
is null
. Throwing ArgumentNullExceptions
in extensions actually is good practise.
如果源为空,那么可枚举类中的每个扩展方法都会抛出一个ArgumentNullException。在扩展中抛出ArgumentNullExceptions实际上是一个很好的练习。