그래서 나는 종종이 상황을 겪습니다 … 여기서 Do.Something(...)
null 컬렉션을 반환합니다 :
int[] returnArray = Do.Something(...);
그런 다음이 컬렉션을 다음과 같이 사용하려고합니다.
foreach (int i in returnArray)
{
// do some more stuff
}
궁금합니다 .foreach 루프가 null 컬렉션에서 작동하지 않는 이유는 무엇입니까? 0 개의 반복이 null 컬렉션으로 실행되는 것이 논리적 인 것 같습니다 … 대신에 NullReferenceException
. 왜 이것이 될 수 있는지 아는 사람이 있습니까?
반환하는 내용이 확실하지 않은 API로 작업하면서 짜증나는 일 이니 if (someCollection != null)
어디에서나 끝납니다 …
편집 :foreach
사용법 을 설명해 주셔서 감사합니다 .GetEnumerator
얻을 열거자가 없으면 foreach가 실패합니다. 열거 형을 잡기 전에 언어 / 런타임이 null 검사를 수행 할 수없는 이유를 묻고있는 것 같습니다. 그 행동은 여전히 잘 정의되어있는 것 같습니다.
답변
짧은 대답은 “컴파일러 디자이너가 설계 한 방식이기 때문입니다.” 그러나 실제로는 컬렉션 객체가 null이므로 컴파일러가 열거자를 통해 컬렉션을 반복 할 수있는 방법이 없습니다.
실제로 이와 같은 작업을 수행 해야하는 경우 null 병합 연산자를 사용해보십시오.
int[] array = null;
foreach (int i in array ?? Enumerable.Empty<int>())
{
System.Console.WriteLine(string.Format("{0}", i));
}
답변
foreach
루프는 호출 GetEnumerator
방법.
컬렉션이 null
이면이 메서드 호출은을 발생 NullReferenceException
시킵니다.
null
컬렉션 을 반환하는 것은 좋지 않습니다 . 대신 메소드가 빈 컬렉션을 반환해야합니다.
답변
빈 컬렉션과 컬렉션에 대한 null 참조에는 큰 차이가 있습니다.
foreach
내부적으로 를 사용 하면 IEnumerable의 GetEnumerator () 메서드 가 호출 됩니다. 참조가 null 인 경우,이 예외가 발생합니다.
그러나 빈 IEnumerable
또는 을 갖는 것은 완벽하게 유효합니다 IEnumerable<T>
. 이 경우, foreach는 컬렉션이 비어 있기 때문에 어떤 것에 대해서도 “반복”하지는 않지만 완벽하게 유효한 시나리오이기 때문에 던지지도 않습니다.
편집하다:
개인적 으로이 문제를 해결 해야하는 경우 확장 방법을 권장합니다.
public static IEnumerable<T> AsNotNull<T>(this IEnumerable<T> original)
{
return original ?? Enumerable.Empty<T>();
}
그런 다음 전화하십시오.
foreach (int i in returnArray.AsNotNull())
{
// do some more stuff
}
답변
그것은 오래 전에 대답하고 있지만 null 포인터 예외를 피하기 위해 다음과 같은 방법 으로이 작업을 시도했지만 C # null check operator?를 사용하는 사람에게 유용 할 수 있습니다.
//fragments is a list which can be null
fragments?.ForEach((obj) =>
{
//do something with obj
});
답변
이 문제를 해결하기위한 또 다른 확장 방법 :
public static void ForEach<T>(this IEnumerable<T> items, Action<T> action)
{
if(items == null) return;
foreach (var item in items) action(item);
}
여러 가지 방법으로 소비하십시오.
(1) T
다음 을 받아들이는 방법
returnArray.ForEach(Console.WriteLine);
(2) 식 :
returnArray.ForEach(i => UpdateStatus(string.Format("{0}% complete", i)));
(3) 여러 줄 익명 방법
int toCompare = 10;
returnArray.ForEach(i =>
{
var thisInt = i;
var next = i++;
if(next > 10) Console.WriteLine("Match: {0}", i);
});
답변
확장 방법을 작성하면 도움이됩니다.
public static class Extensions
{
public static void ForEachWithNull<T>(this IEnumerable<T> source, Action<T> action)
{
if(source == null)
{
return;
}
foreach(var item in source)
{
action(item);
}
}
}
답변
null 컬렉션은 빈 컬렉션과 같지 않기 때문입니다. 빈 컬렉션은 요소가없는 컬렉션 개체입니다. null 컬렉션은 존재하지 않는 개체입니다.
다음은 시도해 볼만한 사항입니다. 두 가지 컬렉션을 모두 선언하십시오. 비어 있도록 하나를 정상적으로 초기화하고 다른 하나에 값을 할당하십시오 null
. 그런 다음 두 컬렉션 모두에 개체를 추가하고 어떻게되는지 확인하십시오.