왜 그럴까요?수집이 null인 경우 각 루프 스로우 NullRefException에 대한 NET?
그래서 이런 상황에 자주 부딪히곤 합니다.어디에Do.Something(...)다음과 같은 null 컬렉션을 반환합니다.
int[] returnArray = Do.Something(...);
그런 다음 이 컬렉션을 다음과 같이 사용하려고 합니다.
foreach (int i in returnArray)
{
// do some more stuff
}
그냥 궁금해서 그러는데, 왜 각 루프는 null 컬렉션에서 작동할 수 없나요?0번의 반복이 null 컬렉션으로 실행되는 것이 논리적으로 보입니다.대신 그것은 a를 던집니다.NullReferenceException왜 이럴 수 있는지 아는 사람?
정확히 무엇이 반환되는지 명확하지 않은 API로 작업하고 있기 때문에 짜증이 납니다.if (someCollection != null)온통.
짧은 대답은 "그것이 컴파일러 설계자들이 설계한 방식이기 때문입니다." 하지만 현실적으로, 여러분의 컬렉션 개체는 null입니다. 그래서 컴파일러가 열거자가 컬렉션을 순환하도록 할 수 있는 방법은 없습니다.
이와 같은 작업을 수행해야 하는 경우 null 병합 연산자를 사용해 보십시오.
int[] array = null;
foreach (int i in array ?? Enumerable.Empty<int>())
{
System.Console.WriteLine(string.Format("{0}", i));
}
A foreach루프가 호출합니다.GetEnumerator방법.
컬렉션이 다음과 같은 경우null이 메서드 호출은 다음과 같은 결과를 낳습니다.NullReferenceException.
a를 반환하는 것은 나쁜 관행입니다.null컬렉션입니다. 대신 메서드가 빈 컬렉션을 반환해야 합니다.
빈 컬렉션과 컬렉션에 대한 null 참조 사이에는 큰 차이가 있습니다.
사용할 때foreach내부적으로는 IEnumberable의 GetEnumerator() 메서드를 호출합니다.참조가 null인 경우 이 예외가 발생합니다.
그러나 비어 있는 것은 완벽하게 유효합니다.IEnumerable또는IEnumerable<T>이 경우 컬렉션이 비어 있기 때문에 각각은 어떤 것에도 대해 "반복"하지 않지만 완전히 유효한 시나리오이기 때문에 던지지도 않습니다.
편집:
개인적으로 이 문제를 해결해야 한다면 확장 방법을 추천합니다.
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 검사 연산자를 사용하는 사람에게 유용할 수 있습니다.
//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);
}
다양한 방법으로 소비:
을 받아들이는 방법으로.T:
returnArray.ForEach(Console.WriteLine);
다음과 같은 표정으로:
returnArray.ForEach(i => UpdateStatus(string.Format("{0}% complete", i)));
다중 행 익명 방식으로
int toCompare = 10;
returnArray.ForEach(i =>
{
var thisInt = i;
var next = i++;
if(next > 10) Console.WriteLine("Match: {0}", i);
});
null 컬렉션은 빈 컬렉션과 동일하지 않기 때문입니다.빈 컬렉션은 요소가 없는 컬렉션 개체이고 null 컬렉션은 존재하지 않는 개체입니다.
여기 시도해 볼 것이 있습니다. 어떤 종류의 컬렉션이든 두 개의 컬렉션을 선언합니다., 하나는 합니다.null그런 다음 두 컬렉션에 개체를 추가하고 어떻게 되는지 확인합니다.
확장 방법을 작성하면 다음과 같은 이점이 있습니다.
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);
}
}
}
은 의잘니의 입니다.Do.Something()여기서 가장 좋은 방법은 null이 아닌 0 크기의 배열을 반환하는 것입니다.
에서 왜하면뒤는서에냐는▁the▁the▁because.foreach다음에 해당하는 열거자를 가져옵니다.
using (IEnumerator<int> enumerator = returnArray.getEnumerator()) {
while (enumerator.MoveNext()) {
int i = enumerator.Current;
// do some more stuff
}
}
예외가 발생하는 이유에 대한 설명은 여기에 제공된 답변과 함께 매우 명확하다고 생각합니다.저는 이 컬렉션들로 제가 평소에 작업하는 방식을 보완하고 싶습니다.때때로 컬렉션을 한 번 이상 사용하고 매번 Null 여부를 테스트해야 하기 때문입니다.이를 방지하기 위해 다음을 수행합니다.
var returnArray = DoSomething() ?? Enumerable.Empty<int>();
foreach (int i in returnArray)
{
// do some more stuff
}
이렇게 하면 예외를 두려워하지 않고 원하는 만큼 컬렉션을 사용할 수 있으며 과도한 조건문으로 코드를 오염시키지 않습니다.
연산자 null 하기 null - " " " 입니다.?.또한 훌륭한 접근 방식입니다.그러나 어레이의 경우(문제의 예와 같이) 다음과 같이 목록으로 변환해야 합니다.
int[] returnArray = DoSomething();
returnArray?.ToList().ForEach((i) =>
{
// do some more stuff
});
SPListItem item;
DataRow dr = datatable.NewRow();
dr["ID"] = (!Object.Equals(item["ID"], null)) ? item["ID"].ToString() : string.Empty;
언급URL : https://stackoverflow.com/questions/3088147/why-does-net-foreach-loop-throw-nullrefexception-when-collection-is-null
'programing' 카테고리의 다른 글
| 페이지를 나가기 전에 저장하지 않은 변경 사항에 대해 사용자에게 경고 (0) | 2023.05.09 |
|---|---|
| 생성자와 ngOnInit의 차이점 (0) | 2023.05.09 |
| 시작 시 단일 양식 숨기기 (0) | 2023.05.09 |
| 문자열의 마지막 단어 바꾸기 - C# (0) | 2023.05.09 |
| C#에서 여러 공간을 단일 공간으로 대체하려면 어떻게 해야 합니까? (0) | 2023.05.09 |