Programing

IEnumerable이 null인지 또는 비어 있는지 확인하는 방법은 무엇입니까?

lottogame 2020. 6. 21. 19:37
반응형

IEnumerable이 null인지 또는 비어 있는지 확인하는 방법은 무엇입니까?


나는 string.IsNullOrEmpty방법을 좋아한다 . IEnumerable에 대해 동일한 기능을 허용하는 것을 갖고 싶습니다. 그런가요? 어쩌면 컬렉션 도우미 클래스일까요? 내가 묻는 이유는 if성명서에서 후두둑이 인 경우 코드가 복잡해 보이기 때문입니다 (mylist != null && mylist.Any()). 갖는 것이 훨씬 더 깨끗합니다 Foo.IsAny(myList).

이 게시물은 그 대답을 제공하지 않습니다 : IEnumerable이 비어 있습니까? .


확실히 당신 그것을 쓸 수 있습니다 :

public static class Utils {
    public static bool IsAny<T>(this IEnumerable<T> data) {
        return data != null && data.Any();
    }
}

그러나 모든 서열이 반복 가능한 것은 아님을주의해야한다. 일반적으로 나는 만일을 위해 그들을 한 번만 걷는 것을 선호합니다.


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

다음은 정적 래퍼 클래스를 포함하는 @Matt Greer의 유용한 답변의 수정 된 버전입니다.이를 복사하여 새 소스 파일에 붙여 넣을 수 있으며 Linq에 의존하지 않고 일반적인 IEnumerable<T>오버로드를 추가하여 값 유형의 권투를 피할 수 있습니다 제네릭이 아닌 버전에서 발생합니다. [편집 : 참고로 IEnumerable<T>열거 자의 복싱을 막을 수는 없지만 , 오리 타이핑으로이를 막을 수는 없지만 최소한 값 유형 컬렉션의 요소는 각각 복싱되지는 않습니다.]

using System.Collections;
using System.Collections.Generic;

public static class IsNullOrEmptyExtension
{
    public static bool IsNullOrEmpty(this IEnumerable source)
    {
        if (source != null)
        {
            foreach (object obj in source)
            {
                return false;
            }
        }
        return true;
    }

    public static bool IsNullOrEmpty<T>(this IEnumerable<T> source)
    {
        if (source != null)
        {
            foreach (T obj in source)
            {
                return false;
            }
        }
        return true;
    }
}

다른 방법은 열거자를 가져와 MoveNext () 메서드를 호출하여 항목이 있는지 확인하는 것입니다.

if (mylist != null && mylist.GetEnumerator().MoveNext())
{
    // The list is not null or empty
}

이것은 IEnumerable 및 IEnumerable <T>에서도 작동합니다.


최신 C # 기능을 활용하여 내가하는 방식 :

옵션 1)

public static class Utils {
    public static bool IsNullOrEmpty<T>(this IEnumerable<T> list) {
        return !(list?.Any() ?? false);
    }
}

옵션 2)

public static class Utils {
    public static bool IsNullOrEmpty<T>(this IEnumerable<T> list) {
        return !(list?.Any()).GetValueOrDefault();
    }
}

그리고 컬렉션이 비어 있는지 확인 Count == 0하거나 Count() == 0확인 하지 마십시오 . 항상 Linq를 사용하십시오.Any()


도움이 될 수 있습니다

public static bool IsAny<T>(this IEnumerable<T> enumerable)
{
    return enumerable?.Any() == true;
}

public static bool IsNullOrEmpty<T>(this IEnumerable<T> enumerable)
{
    return enumerable?.Any() != true;
}

C # 6부터는 null 전파를 사용할 수 있습니다 .myList?.Any() == true

그래도 너무 애매하거나 확장 방법을 선호한다면 Matt Greer와 Marc Gravell의 답변을 추천하지만 완벽 함을 위해 약간의 확장 기능이 있습니다.

그들의 대답은 동일한 기본 기능을 제공하지만 각각 다른 관점에서 볼 수 있습니다. Matt의 대답은- string.IsNullOrEmpty정직성을 사용하는 반면 Marc의 대답은 Linq의 .Any()길을 따라 작업을 완료합니다.

개인적으로 .Any()도로 를 사용 하려고하지만 메소드의 다른 과부하 에서 상태 확인 기능을 추가하고 싶습니다 .

    public static bool AnyNotNull<T>(this IEnumerable<T> source, Func<T, bool> predicate = null)
    {
        if (source == null) return false;
        return predicate == null
            ? source.Any()
            : source.Any(predicate);
    }

따라서 여전히 다음과 같은 작업을 수행 할 수 있습니다 : myList.AnyNotNull(item=>item.AnswerToLife == 42);일반과 함께 할 수 .Any()있지만 null 검사를 추가하면

C # 6 방식을 사용 하면`bool myList?.Any()bool?아닌 오히려 null 전파 하는 실제 효과를 반환합니다.


다음은 Marc Gravell 's answer 의 코드 와 사용 예입니다.

using System;
using System.Collections.Generic;
using System.Linq;

public static class Utils
{
    public static bool IsAny<T>(this IEnumerable<T> data)
    {
        return data != null && data.Any();
    }
}

class Program
{
    static void Main(string[] args)
    {
        IEnumerable<string> items;
        //items = null;
        //items = new String[0];
        items = new String[] { "foo", "bar", "baz" };

        /*** Example Starts Here ***/
        if (items.IsAny())
        {
            foreach (var item in items)
            {
                Console.WriteLine(item);
            }
        }
        else
        {
            Console.WriteLine("No items.");
        }
    }
}

그가 말했듯이 모든 시퀀스가 ​​반복 가능한 것은 아니므로 시퀀스를 IsAny()단계별로 시작 하기 때문에 코드에서 문제를 일으킬 수 있습니다 . 나는 무엇을 의심 로버트 하비의 대답 의미는 자주 확인하지 않아도했다 null 비 웁니다. 종종 null을 확인한 다음을 사용할 수 있습니다 foreach.

시퀀스를 두 번 시작하지 않고를 활용하기 위해 foreach다음과 같은 코드를 작성했습니다.

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main(string[] args)
    {
        IEnumerable<string> items;
        //items = null;
        //items = new String[0];
        items = new String[] { "foo", "bar", "baz" };

        /*** Example Starts Here ***/
        bool isEmpty = true;
        if (items != null)
        {
            foreach (var item in items)
            {
                isEmpty = false;
                Console.WriteLine(item);
            }
        }
        if (isEmpty)
        {
            Console.WriteLine("No items.");
        }
    }
}

확장 방법을 사용하면 두 줄의 입력 줄을 절약 할 수 있지만이 코드는 더 명확 해 보입니다. 일부 개발자는 이것이 IsAny(items)실제로 시퀀스를 단계별로 시작 한다는 것을 즉시 인식하지 못할 것이라고 생각합니다 . (물론 많은 시퀀스를 사용하는 경우 시퀀스를 통해 어떤 단계를 거치는 지 생각하는 법을 빨리 배우게됩니다.)


사용 Bool IsCollectionNullOrEmpty = !(Collection?.Any()??false);합니다. 도움이 되었기를 바랍니다.

고장:

Collection?.Any()nullCollection이 null이고 falseCollection이 비어 있으면 반환 됩니다 .

Collection?.Any()??falsefalseCollection이 비어 있고 Collection이이면 우리에게 줄 것 false입니다 null.

그것의 보완은 우리에게 줄 것이다 IsEmptyOrNull.


if (collection?.Any() == true){
    // if collection contains more than one item
}
if (collection?.Any() != true){
    // if collection is null
    // if collection does not contain any item
}

나는 같은 문제가 있었고 다음과 같이 해결했다.

    public bool HasMember(IEnumerable<TEntity> Dataset)
    {
        return Dataset != null && Dataset.Any(c=>c!=null);
    }

"c=>c!=null" will ignore all the null entities.


I built this off of the answer by @Matt Greer

He answered the OP's question perfectly.

I wanted something like this while maintaining the original capabilities of Any while also checking for null. I'm posting this in case anyone else needs something similar.

Specifically I wanted to still be able to pass in a predicate.

public static class Utilities
{
    /// <summary>
    /// Determines whether a sequence has a value and contains any elements.
    /// </summary>
    /// <typeparam name="TSource">The type of the elements of source.</typeparam>
    /// <param name="source">The <see cref="System.Collections.Generic.IEnumerable"/> to check for emptiness.</param>
    /// <returns>true if the source sequence is not null and contains any elements; otherwise, false.</returns>
    public static bool AnyNotNull<TSource>(this IEnumerable<TSource> source)
    {
        return source?.Any() == true;
    }

    /// <summary>
    /// Determines whether a sequence has a value and any element of a sequence satisfies a condition.
    /// </summary>
    /// <typeparam name="TSource">The type of the elements of source.</typeparam>
    /// <param name="source">An <see cref="System.Collections.Generic.IEnumerable"/> whose elements to apply the predicate to.</param>
    /// <param name="predicate">A function to test each element for a condition.</param>
    /// <returns>true if the source sequence is not null and any elements in the source sequence pass the test in the specified predicate; otherwise, false.</returns>
    public static bool AnyNotNull<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
    {
        return source?.Any(predicate) == true;
    }
}

The naming of the extension method could probably be better.


just add using System.Linq and see the magic happening when you try to access the available methods in the IEnumerable. Adding this will give you access to method named Count() as simple as that. just remember to check for null value before calling count() :)


I used simple if to check for it

check out my solution

foreach (Pet pet in v.Pets)
{
    if (pet == null)
    {
        Console.WriteLine(" No pet");// enumerator is empty
        break;
    }
    Console.WriteLine("  {0}", pet.Name);
}

The other best solution as below to check empty or not ?

for(var item in listEnumerable)
{
 var count=item.Length;
  if(count>0)
  {
         // not empty or null
   }
  else
  {
       // empty
  }
}

I use this one:

    public static bool IsNotEmpty(this ICollection elements)
    {
        return elements != null && elements.Count > 0;
    }

Ejem:

List<string> Things = null;
if (Things.IsNotEmpty())
{
    //replaces ->  if (Things != null && Things.Count > 0) 
}

Since some resources are exhausted after one read, I thought why not combine the checks and the reads, instead of the traditional separate check, then read.

First we have one for the simpler check-for-null inline extension:

public static System.Collections.Generic.IEnumerable<T> ThrowOnNull<T>(this System.Collections.Generic.IEnumerable<T> source, string paramName = null) => source ?? throw new System.ArgumentNullException(paramName ?? nameof(source));

var first = source.ThrowOnNull().First();

Then we have the little more involved (well, at least the way I wrote it) check-for-null-and-empty inline extension:

public static System.Collections.Generic.IEnumerable<T> ThrowOnNullOrEmpty<T>(this System.Collections.Generic.IEnumerable<T> source, string paramName = null)
{
  using (var e = source.ThrowOnNull(paramName).GetEnumerator())
  {
    if (!e.MoveNext())
    {
      throw new System.ArgumentException(@"The sequence is empty.", paramName ?? nameof(source));
    }

    do
    {
      yield return e.Current;
    }
    while (e.MoveNext());
  }
}

var first = source.ThrowOnNullOrEmpty().First();

You can of course still call both without continuing the call chain. Also, I included the paramName, so that the caller may include an alternate name for the error if it's not "source" being checked, e.g. "nameof(target)".


 public static bool AnyNotNull<TSource>(this IEnumerable<TSource> source)
    {
        return source != null && source.Any();
    }

my own extension method to check Not null and Any

참고URL : https://stackoverflow.com/questions/5047349/how-to-check-if-ienumerable-is-null-or-empty

반응형