[c#] C #에 “Empty List”싱글 톤이 있습니까?

C #에서는 LINQ와 IEnumerable을 잘 사용합니다. 그리고 모든 것이 훌륭합니다 (또는 적어도 대부분 그렇습니다).

그러나 대부분의 경우 IEnumerable<X>기본값으로 비어 있어야합니다 . 즉,

for (var x in xs) { ... }

null 검사없이 작동합니다. 이제 이것은 더 큰 맥락에 따라 현재 내가하는 일입니다.

var xs = f() ?? new X[0];              // when xs is assigned, sometimes
for (var x in xs ?? new X[0]) { ... }  // inline, sometimes

이제 위의 내용은 나에게 완벽하게 괜찮지 만, 즉 배열 객체를 만드는 데 “추가 오버 헤드”가 있으면 신경 쓰지 않습니다 . 궁금합니다.

C # /. NET에 “빈 변경 불가능한 IEnumerable / IList”싱글 톤이 있습니까? (그렇지 않더라도 위에서 설명한 사례를 처리하는 “더 나은”방법이 있습니까?)

Java는 제네릭이 다르게 처리되기 때문에 유사한 개념이 C #에서도 작동 할 수 있는지 확실하지 않지만 Collections.EMPTY_LIST“잘 형식화 된”을 통해 불변의 싱글 톤을 가지고 Collections.emptyList<T>()있습니다.

감사.



답변

을 찾고 있습니다 Enumerable.Empty<T>().

다른 소식에서 Java 빈 목록은 List 인터페이스가 예외를 발생시키는 목록에 요소를 추가하는 메소드를 노출하기 때문에 짜증납니다.


답변

Enumerable.Empty<T>() 바로 그것입니다.


답변

나는 당신이 찾고 있다고 생각합니다 Enumerable.Empty<T>().

목록이 종종 변경 가능하기 때문에 빈 목록 싱글 톤은 그다지 의미가 없습니다.


답변

원래 예제에서는 빈 배열을 사용하여 빈 열거 형을 제공합니다. 사용하는 Enumerable.Empty<T>()것이 완벽 하지만 다른 경우가있을 수 있습니다 . 배열 (또는 IList<T>인터페이스)을 사용해야하는 경우 방법을 사용할 수 있습니다.

System.Array.Empty<T>()

불필요한 할당을 피하는 데 도움이됩니다.

참고 / 참조 :


답변

확장 메서드를 추가하는 것은 null을 처리 할 수있는 능력 덕분에 깨끗한 대안이라고 생각합니다.

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

  foreach(var x in xs.EmptyIfNull())
  {
    ...
  }


답변

Microsoft는 다음과 같이`Any () ‘를 구현했습니다 ( source ).

public static bool Any<TSource>(this IEnumerable<TSource> source)
{
    if (source == null) throw new ArgumentNullException("source");
    using (IEnumerator<TSource> e = source.GetEnumerator())
    {
        if (e.MoveNext()) return true;
    }
    return false;
}

를 호출하는 확장 메서드를 작성하는 대신 호출 스택에 호출을 저장하려면 !Any()다음 세 가지 변경을 다시 작성하면됩니다.

public static bool IsEmpty<TSource>(this IEnumerable<TSource> source) //first change (name)
{
    if (source == null) throw new ArgumentNullException("source");
    using (IEnumerator<TSource> e = source.GetEnumerator())
    {
        if (e.MoveNext()) return false; //second change
    }
    return true; //third change
}


답변

Enumerable.Empty<T>()목록과 함께 사용 하면 단점이 있습니다. 당신이 손 경우 Enumerable.Empty<T>목록 생성자에 다음 4 사이즈의 배열을 할당 할 수 있습니다. 그러나 Collection목록 생성자에 빈 을 건네면 할당이 발생하지 않습니다. 따라서 코드 전체에서이 솔루션을 사용하면 IEnumerables 중 하나가 목록을 구성하는 데 사용되어 불필요한 할당이 발생합니다.