为什么Any()不能处理ac#null对象

Def*_*Day 44 .net c# ienumerable object

在null对象上调用Any()时,它会在C#中抛出ArgumentNullException.如果对象为null,那么肯定没有'any',它应该返回false.

为什么C#以这种方式运行?

Cod*_*aos 130

Any() 问:"这个盒子包含任何物品吗?"

如果框是空的,答案显然是否定的.

但如果首先没有盒子,那么这个问题没有意义,而且这个功能抱怨道:"你到底在说什么?没有盒子."

  • 没有勺子 (20认同)
  • @Dscoduc你可以使用 `?.Any() ?? false` 或 `?.Any() == true`。如果您想使用我的答案中的扩展方法,则可以选择“.OrEmpty().Any()”。 (4认同)
  • 但这就是问题的重点。我参与过的每个项目(大多数)都有类似的扩展方法。为什么不内置 NotNull() 或 NotNullOrAny() 方法 (2认同)

Jon*_*Jon 39

处理引用类型时,null值在语义上与"空"值不同.

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

如果Any不是扩展方法,则调用它将null导致NullReferenceException.因为它一个扩展方法,抛出一些异常(虽然没有必要)是一个好主意,因为它保留了试图调用方法的众所周知的语义null:BOOM!

  • 虽然这是正确的,但我相信这些都是过时的语义.某人通常想要的是"Any()"/"Where()"/"Select()"/ etc.对此事件进行调用甚至"foreach"迭代就是知道那里是否有任何东西,如果有什么东西可以做某事.在无意义的实例化或空检查中存在如此多的代码浪费.我们得到了?运营商.全力以赴,为扩展方法提供了不错的null功能. (4认同)

Jax*_*ian 36

使用现代C#,您可以通过如下简单检查轻松处理OP的场景:

List<string> foo = null;

if (foo?.Any() ?? false)
{
    DoStuff();
}
Run Code Online (Sandbox Code Playgroud)

这有点像AnyOrDefault(bool default)OP期望Any()扩展方法做的蹩脚实现.

您可以轻松地将其转换为这样的扩展:

public static bool HasItems<T>(this IEnumerable<T> source)
{
    return (source?.Any() ?? false);
}
Run Code Online (Sandbox Code Playgroud)

老实说,我真的不喜欢这个名字AnyOrDefault,因为传递一个默认值是没有意义的(默认值为true可能对以后阅读代码的人来说非常有意义).

  • `public static bool IsNullOrEmpty <T>(这个IEnumerable <T> source){return source?.Any()!= true; 类似于`String.IsNullOrEmpty(stringything)` (4认同)
  • 小意见:我个人觉得`if(foo?.Any()== true)`比``更容易掌握?假)`.前者的英文是"如果有的话是真的那么......",而后者本质上是一个两步的逻辑陈述; 难以解释.它的类似"if any(但将null视为false)然后......". (2认同)
  • “ AnyOrDefault”的替代名称可能是“ HasItems”,或更明确的是“ AnyAndNotNull”。和FWIW一样,您的“ AnyOrDefault”中的“ Default”将引用Source类型的Default,即IEnumerable的“ null”-与Boolean的默认值“ false”无关。因此,该名称具有误导性,因为“ AnyOrDefault”在逻辑上将表示“任何或空值(因为这是默认值)”,因此将为空返回“ true”。这显然不是你的意思。 (2认同)

Fré*_*idi 5

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

您可以事先自行检查:

bool hasAny = yourData == null ? false : yourData.Any(yourPredicate);
Run Code Online (Sandbox Code Playgroud)