Does C# have IsNullOrEmpty for List/IEnumerable?

2019-01-30 22:21发布

I know generally empty List is more prefer than NULL. But I am going to return NULL, for mainly two reasons

  1. I have to check and handle null values explicitly, avoiding bugs and attacks.
  2. It is easy to perform ?? operation afterwards to get a return value.

For strings, we have IsNullOrEmpty. Is there anything from C# itself doing the same thing for List or IEnumerable?

9条回答
在下西门庆
2楼-- · 2019-01-30 22:29

nothing baked into the framework, but it's a pretty straight forward extension method.

See here

/// <summary>
    /// Determines whether the collection is null or contains no elements.
    /// </summary>
    /// <typeparam name="T">The IEnumerable type.</typeparam>
    /// <param name="enumerable">The enumerable, which may be null or empty.</param>
    /// <returns>
    ///     <c>true</c> if the IEnumerable is null or empty; otherwise, <c>false</c>.
    /// </returns>
    public static bool IsNullOrEmpty<T>(this IEnumerable<T> enumerable)
    {
        if (enumerable == null)
        {
            return true;
        }
        /* If this is a list, use the Count property for efficiency. 
         * The Count property is O(1) while IEnumerable.Count() is O(N). */
        var collection = enumerable as ICollection<T>;
        if (collection != null)
        {
            return collection.Count < 1;
        }
        return !enumerable.Any(); 
    }

Daniel Vaughan takes the extra step of casting to ICollection (where possible) for performance reasons. Something I would not have thought to do.

查看更多
劫难
3楼-- · 2019-01-30 22:33

Late update: since C# 6.0, the null-propagation operator may be used to express concise like this:

if (enumerable?.Any() ?? false)

Note 1: ?? false is necessary, because of the following reason (summary/quote from this post):

?. operator will return null if a child member is null. But [...] if we try to get a non-Nullable member, like the Any() method, that returns bool [...] the compiler will "wrap" a return value in Nullable<>. For example, Object?.Any() will give us bool? (which is Nullable<bool>), not bool. [...] Since it can't be implicitly casted to bool this expression cannot be used in the if

Note 2: as a bonus, the statement is also "thread-safe" (quote from answer of this question):

In a multithreaded context, if [enumerable] is accessible from another thread (either because it's a field that's accessible or because it's closed over in a lambda that is exposed to another thread) then the value could be different each time it's computed [i.e.prior null-check]

查看更多
疯言疯语
4楼-- · 2019-01-30 22:36

Putting together the previous answers into a simple extension method for C# 6.0+:

    public static bool IsNullOrEmpty<T>(this IEnumerable<T> me) => !me?.Any() ?? true;
查看更多
5楼-- · 2019-01-30 22:37
var nullOrEmpty = list == null || !list.Any();
查看更多
劫难
6楼-- · 2019-01-30 22:43

As everyone else has said, nothing is built into the framework, but if you are using Castle then Castle.Core.Internal has it.

using Castle.Core.Internal;

namespace PhoneNumbers
{
    public class PhoneNumberService : IPhoneNumberService
    {
        public void ConsolidateNumbers(Account accountRequest)
        {
            if (accountRequest.Addresses.IsNullOrEmpty()) // Addresses is List<T>
            {
                return;
            }
            ...
查看更多
何必那么认真
7楼-- · 2019-01-30 22:46

There is nothing built in.

It is a simple extension method though:

public static bool IsNullOrEmpty<T>(this IEnumerable<T> enumerable)
{
  if(enumerable == null)
    return true;

  return !enumerable.Any();
}
查看更多
登录 后发表回答