developer tip

C #에 List / IEnumerable에 대한 IsNullOrEmpty가 있습니까?

optionbox 2020. 11. 20. 08:52
반응형

C #에 List / IEnumerable에 대한 IsNullOrEmpty가 있습니까?


일반적으로 빈 목록이 NULL보다 선호된다는 것을 알고 있습니다. 하지만 주로 두 가지 이유로 NULL을 반환합니다.

  1. 버그와 공격을 피하기 위해 명시 적으로 null 값을 확인하고 처리해야합니다.
  2. ??반환 값을 얻기 위해 나중에 작업 을 수행하는 것이 쉽습니다 .

문자열의 경우 IsNullOrEmpty가 있습니다. 거기에 무엇입니까 C # 자체에서 목록 또는 IEnumerable을 위해 같은 일을하고있는가?


프레임 워크에 구워진 것은 없지만 매우 간단한 확장 방법입니다.

여길 봐

/// <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은 성능상의 이유로 ICollection (가능한 경우)으로 캐스팅하는 추가 단계를 수행합니다. 내가 할 생각이 없었을 것입니다.


후기 업데이트 : C # 6.0부터 null 전파 연산자를 사용하여 다음과 같이 간결하게 표현할 수 있습니다.

if (  list?.Count  > 0 ) // For List<T>
if ( array?.Length > 0 ) // For Array<T>

또는 다음에 대한 더 깨끗하고 일반적인 대안으로 IEnumerable<T>:

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

참고 1 :IsNotNullOrEmpty OP 질문 ( quote ) 과 달리 모든 상위 변형은 실제로를 반영합니다 .

연산자 우선 순위 IsNullOrEmpty등가물 때문에 덜 매력적으로 보입니다.
if (!(list?.Count > 0))

참고 2 : ?? false 다음과 같은 이유로 필요합니다 ( 이 게시물의 요약 / 인용 ).

?.연산자는 null자식 멤버가 인 경우 반환 됩니다 null. 그러나 [...] 메소드 Nullable처럼 멤버 를 얻으려고하면 [...] Any()를 반환 bool하는 컴파일러는 Nullable<>. 예를 들어, Object?.Any()우리를 줄 것이다 bool?(인 Nullable<bool>) 없습니다 bool. [...] 암시 적 bool으로이 식으로 캐스팅 할 수 없기 때문에if

참고 3 : 보너스 로이 문장은 "스레드로부터 안전"합니다 ( 이 질문에 대한 답변에서 인용 ).

다중 스레드 컨텍스트에서 [ enumerable ]이 다른 스레드에서 액세스 할 수있는 경우 (액세스 가능한 필드이거나 다른 스레드에 노출 된 람다에서 닫혀 있기 때문에) 값이 계산 될 때마다 다를 수 있습니다 [ ieprior null -확인 ]


내장 된 것이 없습니다.

하지만 간단한 확장 방법입니다.

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

  return !enumerable.Any();
}

var nullOrEmpty = list == null || !list.Any();

이전 답변을 C # 6.0 이상에 대한 간단한 확장 방법에 통합 :

    public static bool IsNullOrEmpty<T>(this IEnumerable<T> me) => !me?.Any() ?? true;

비어 있지 않은 경우 모든 요소를 ​​검색 할 수 있어야한다면 Any()되감기 불가능한 열거 형에 대한 호출이 요소를 "잊어 버릴" 것이기 때문에 여기에있는 일부 답변이 작동하지 않습니다 .

다른 접근 방식을 취하고 null을 비움으로 바꿀 수 있습니다.

bool didSomething = false;
foreach(var element in someEnumeration ?? Enumerable.Empty<MyType>())
{
  //some sensible thing to do on element...
  didSomething = true;
}
if(!didSomething)
{
  //handle the fact that it was null or empty (without caring which).
}

마찬가지로 (someEnumeration ?? Enumerable.Empty<MyType>()).ToList()등을 사용할 수 있습니다.


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;
            }
            ...

I modified the suggestion from Matthew Vines to avoid the "Possible multiple enumeration of IEnumerable" - problem. (see also the comment from Jon Hanna)

public static bool IsNullOrEmpty(this IEnumerable items)
    => items == null
    || (items as ICollection)?.Count == 0
    || !items.GetEnumerator().MoveNext();

... and the unit test:

[Test]
public void TestEnumerableEx()
{
    List<int> list = null;
    Assert.IsTrue(list.IsNullOrEmpty());

    list = new List<int>();
    Assert.IsTrue(list.IsNullOrEmpty());

    list.AddRange(new []{1, 2, 3});
    Assert.IsFalse(list.IsNullOrEmpty());

    var enumerator = list.GetEnumerator();
    for(var i = 1; i <= list.Count; i++)
    {
        Assert.IsFalse(list.IsNullOrEmpty());
        Assert.IsTrue(enumerator.MoveNext());
        Assert.AreEqual(i, enumerator.Current);
    }

    Assert.IsFalse(list.IsNullOrEmpty());
    Assert.IsFalse(enumerator.MoveNext());
}

for me best isNullOrEmpty method is looked like this

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

var nullOrEmpty = !( list?.Count > 0 );

참고URL : https://stackoverflow.com/questions/8582344/does-c-sharp-have-isnullorempty-for-list-ienumerable

반응형