为什么 Any() 不适用于 ac# null 对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11538243/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 18:11:25  来源:igfitidea点击:

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

c#.netobjectienumerable

提问by DefenestrationDay

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.

在空对象上调用Any()时,它会在 C# 中引发 ArgumentNullException。如果对象为空,则肯定没有“任何”,它可能应该返回 false。

Why does C# behave this way?

为什么 C# 会这样?

采纳答案by Jon

When dealing with reference types, a nullvalue is semantically different from an "empty" value.

在处理引用类型时,null值在语义上与“空”值不同。

A nullstring is not the same as string.Empty, and a nullIEnumerable<T>is not the same as Enumerable.Empty<T>(or any other "empty" enumerable of that type).

null串是不一样的string.Empty,并且nullIEnumerable<T>是不一样的 Enumerable.Empty<T>(或任何其他“空”可枚举该类型的)。

If Anywere not an extension method, calling it on nullwould result in NullReferenceException. Since it isan 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. 由于它一个扩展方法,抛出一些异常(尽管不是必需的)是一个好主意,因为它保留了尝试调用方法的众所周知的语义nullBOOM!

回答by Dan Puzey

The Anymethod runs against an IEnumerableand 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方法针对 an 运行IEnumerable并告诉您Enumerable 中是否有任何项目。如果你不给它任何枚举,那么 ArgumentNullException 是合理的:没有(匹配)元素的集合与没有集合不同。

回答by Frédéric Hamidi

Any()is an extension method, so thisis actually passed as the first argument to the method. In this situation, it's understandable for it to throw ArgumentNullExceptionis thisis null.

Any()是一个扩展方法,所以this实际上是作为第一个参数传递给方法的。在这种情况下,它抛出ArgumentNullExceptionisthis是可以理解的null

You can perform the check yourself beforehand:

您可以事先自行检查:

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

回答by CodesInChaos

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

但是如果一开始就没有盒子,那么这个问题就没有意义了,函数会抱怨:“你到底在说什么?没有盒子。”



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

这可以与所有 LINQ 方法结合使用foreach,而不仅仅是.Any().

回答by roxioam

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

因为 Any() 它是这样的扩展方法:

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

回答by Tim Schmelter

As others have already mentioned, Anychecks whether or not a sequence contains elements. It does not prevent you from passing nullvalues(what might the bug in the first place).

正如其他人已经提到的,Any检查序列是否包含元素。它不会阻止您传递null值(首先可能是什么错误)。

Every extension method in Enumerableclassthrows an an ArgumentNullExceptionif the sourceis null. Throwing ArgumentNullExceptionsin extensions actually is good practise.

在每一个扩展方法Enumerable抛出的ArgumentNullException,如果sourcenull。扔ArgumentNullExceptions在扩展其实是很好的做法

回答by Jaxidian

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 HasItems<T>(this IEnumerable<T> source)
{
    return (source?.Any() ?? false);
}

Honestly, I don't really like the name AnyOrDefaultfor 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!

老实说,我真的不喜欢这个名字AnyOrDefault,因为传递默认值永远没有意义(默认值 true 对以后阅读代码的人来说可能很刻薄)。HasItems按照评论中的建议重命名为。这是一个更好的名字!

回答by proximab

Any()is an extension method that throws ArgumentNullExceptionif 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.

Any()是一个扩展方法,ArgumentNullException如果源为空则抛出。你会什么都不做吗?一般来说,最好获得一些关于代码中发生的事情的明确指示,而不是默认值。

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 Anywhich makes our code shorter and simpler.

我只是想与您分享一些我公司正在遵循的实用建议。我们编写与私有 NuGet 共享的自定义包,这些包在我们的产品中广泛使用。检查列表是否为空/空非常频繁,所以我们决定编写我们的实现Any,使我们的代码更短更简单。