对 null IEnumerables 进行 Count() 返回零

发布于 2024-09-15 09:52:24 字数 328 浏览 4 评论 0原文

我厌倦了使用这样的代码:

var count = 0;
if (myEnumerable != null)
{
    count = myEnumerable.Count();
}

这有点迂腐:

var count = (myEnumerable ?? new string[0]).Count();

有没有更简洁的方法来做到这一点?我曾经在 IEnumerable<> 上有一个(名字很糟糕的)PhantomCount 扩展方法。它使用了我的第一个代码示例,但它有一些味道(除了名称之外)。

I'm getting tired of using code like this:

var count = 0;
if (myEnumerable != null)
{
    count = myEnumerable.Count();
}

And this is a bit pedantic:

var count = (myEnumerable ?? new string[0]).Count();

Is there any tidier way of doing this? I once had a (badly named) PhantomCount extension method on IEnumerable<> that used my first code example, but it had something of a smell about it (besides the name).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

童话 2024-09-22 09:52:24

问题实际上在于创建这些可枚举的内容。除非您有充分的理由,否则任何生成可迭代集合的内容都应返回空集合,而不是 null。这将与 Null-Object-Pattern 保持一致,因此好处是相同的。

我的建议是修复生成 myEnumerable 的任何内容,或者如果您无法执行此操作,请提前添加一个检查方式以查看它是否为 null 并做出适当的反应。

The problem is really in whatever is creating these enumerables. Unless you have a really good reason, anything that generates an iterable collection should return an empty collection instead of null. This would align with the Null-Object-Pattern, hence the benefits are the same.

My suggestion would be to fix whatever produces myEnumerable, or if you can't do this, add a check way earlier to see if it's null and react appropriately.

弃爱 2024-09-22 09:52:24

怎么样

count = myEnumerable == null? 0 : myEnumerable.Count()

How about

count = myEnumerable == null? 0 : myEnumerable.Count()
浮萍、无处依 2024-09-22 09:52:24

我不认为使用扩展方法是一个坏主意。

public static int NullableCount<T>(this IEnumerable<T> collection)
{
   return collection == null ? 0 : collection.Count();
}

I don't think using extension method is a bad idea.

public static int NullableCount<T>(this IEnumerable<T> collection)
{
   return collection == null ? 0 : collection.Count();
}
扮仙女 2024-09-22 09:52:24

2019 年,最简洁的方法是 var count = myEnumerable?.Count() ?? 0;。

2021年编辑:

public int CountNullable<T>(this IEnumerable<T>? enumerable) =>
    enumerable?.Count() ?? 0;

In 2019 the tidiest way to do this is var count = myEnumerable?.Count() ?? 0;.

2021 edit:

public int CountNullable<T>(this IEnumerable<T>? enumerable) =>
    enumerable?.Count() ?? 0;
装迷糊 2024-09-22 09:52:24

我使用自定义扩展方法:

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

...

int count = myEnumerable.EmptyIfNull().Count();

I use a custom extension method:

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

...

int count = myEnumerable.EmptyIfNull().Count();
揽月 2024-09-22 09:52:24

我还会编写自己的扩展方法 CountOrZeroForNull,如其他答案所示。

此外...而不是:

var count = (myEnumerable ?? new string[0]).Count();
                          // ^^^^^^^^^^^^^

您可以写:

var count = (myEnumerable ?? Enumerable.Empty<string>()).Count();
                          // ^^^^^^^^^^^^^^^^^^^^^^^^^^

这并不能缓解您的特定问题,但它可以避免分配未使用的数组。 (Enumerable.Empty 最有可能实现为简单的 yield break 语句。)

I would also write my own extension method CountOrZeroForNull, as shown in other answers.

Besides... Instead of:

var count = (myEnumerable ?? new string[0]).Count();
                          // ^^^^^^^^^^^^^

you could write:

var count = (myEnumerable ?? Enumerable.Empty<string>()).Count();
                          // ^^^^^^^^^^^^^^^^^^^^^^^^^^

This doesn't alleviate your specific problem, but it circumvents allocation of an unused array. (Enumerable.Empty<T> is most likely implemented as a simple yield break statement.)

眼趣 2024-09-22 09:52:24

只需创建您自己的扩展方法来根据您的意愿处理空枚举。

public int CountOrNull<T>(this IEnumerable<T> source)
{
    return source == null ? 0 : source.Count();
}

然后您可以简单地使用:

var list1 = new int[] { 1, 2, 3, 4 };
var list2 = (int[])null;

var count1 = list1.CountOrNull(); // 4
var count2 = list2.CountOrNull(); // 0

这就是扩展方法的伟大之处。即使(您似乎)调用该方法的对象为 null,它们仍然可以正常工作。

Just create your own extension method that handles null enumerables as you wish.

public int CountOrNull<T>(this IEnumerable<T> source)
{
    return source == null ? 0 : source.Count();
}

You can then simply use:

var list1 = new int[] { 1, 2, 3, 4 };
var list2 = (int[])null;

var count1 = list1.CountOrNull(); // 4
var count2 = list2.CountOrNull(); // 0

That's the great thing about extension methods. They still work fine even if the object on which (you appear to be) calling the method is null.

与他有关 2024-09-22 09:52:24

如果返回值为 0,您将采取什么措施?

如果这很有趣,也许您应该对 IEnumerable 使用 Haack 的 IsNullOrEmpty 扩展方法,如下所示:

public static bool IsNullOrEmpty<T>(this IEnumerable<T> items) 
{
    return items == null || !items.Any();
}

链接为 http://haacked.com/archive/2010/06/10/checking-for-empty-enumerations.aspx

作为博客上的评论发布,您还会发现我为此编写的一个 Exception 类:

public class ArgumentNullOrEmptyException : ArgumentNullException
{
    public ArgumentNullOrEmptyException( string paramName ) : base( paramName )
    {}

    public ArgumentNullOrEmptyException( string paramName, string message ) : base( paramName, message )
    {}

    public override string Message
    {
        get
        {
            return "Value cannot be null nor empty.{0}Parameter name: {1}".FormatWith( Environment.NewLine, ParamName );
        }
    }
}

What actions are you taking if the value returned is 0?

If that's what's interesting, maybe you should use Haack's IsNullOrEmpty extension method for IEnumerable like so:

public static bool IsNullOrEmpty<T>(this IEnumerable<T> items) 
{
    return items == null || !items.Any();
}

The link is http://haacked.com/archive/2010/06/10/checking-for-empty-enumerations.aspx

Posted as a comment on the blog, you'll also find an Exception class I wrote to go with that:

public class ArgumentNullOrEmptyException : ArgumentNullException
{
    public ArgumentNullOrEmptyException( string paramName ) : base( paramName )
    {}

    public ArgumentNullOrEmptyException( string paramName, string message ) : base( paramName, message )
    {}

    public override string Message
    {
        get
        {
            return "Value cannot be null nor empty.{0}Parameter name: {1}".FormatWith( Environment.NewLine, ParamName );
        }
    }
}
疾风者 2024-09-22 09:52:24
var count = 0; 

if (myEnumerable != null) 
    count = myEnumerable.Count(); 

虽然它不像其他答案那么技术性,但它是最具可读性的。

var count = 0; 

if (myEnumerable != null) 
    count = myEnumerable.Count(); 

While it's not as technical as the other answers, it's far the most readable.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文