Why doesn't Any() work on a c# null object

こ雲淡風輕ζ 提交于 2020-08-21 04:57:28

问题


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.

Why does C# behave this way?


回答1:


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).

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!




回答2:


Any() is asking: "Does this box contain any items?"

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."


When I want to treat a missing collection like an empty one, I use the following extension method:

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

This can be combined with all LINQ methods and foreach, not just .Any().




回答3:


With modern C#, you can easily handle the OP's scenario with a simple check like this:

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.

You could easily make this into an extension like this:

public static bool HasItems<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). Renamed to HasItems, as suggested in the comments. This is a far better name!




回答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.

You can perform the check yourself beforehand:

bool hasAny = yourData == null ? false : yourData.Any(yourPredicate);



回答5:


Because Any() it is a extension method like this:

public static bool Any(this IEnumerable enumerable)
{
    if (enumerable == null)
        throw ArgumentNullException("enumerable");
    ...
}



回答6:


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.




回答7:


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.




回答8:


Any() is an extension method that throws ArgumentNullException if the source is null. Would you perform an action on nothing? In general, it's better to get some explicit indicator of what's happening in the code rather than the default value.

But it doesn't mean it can't be like that. If you know what you doing, write your own custom implementation.

I just wanted to share with you some practical advice my company is following. We write our custom packages shared with private NuGet that are widely used in our products. Checking if the list is null/empty is very frequent, so we decided to write our implementation of Any which makes our code shorter and simpler.



来源:https://stackoverflow.com/questions/11538243/why-doesnt-any-work-on-a-c-sharp-null-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!