확장 메소드를 만들 때 물론 호출 할 수 있습니다 null
. 그러나 인스턴스 메소드 호출과 달리 null 호출 은 -> 던질 필요 가 없습니다 NullReferenceException
-> 수동으로 확인하고 던질 필요가 없습니다.
Linq 확장 방법의 구현을 위해 Any()
Microsoft는 ArgumentNullException
( https://github.com/dotnet/corefx/blob/master/src/System.Linq/src/System/Linq/AnyAll.cs )를 던져야한다고 결정했습니다 .
글을 써야 돼 if( myCollection != null && myCollection.Any() )
이 코드의 클라이언트로서 예를 들어 ((int[])null).Any()
반환해야한다고 잘못 생각 false
합니까?
답변
5 개의 감자가 담긴 가방이 있습니다. 이 있습니까 .Any()
감자 가방에?
” 네 “라고 말합니다.<= true
나는 모든 감자를 꺼내 먹습니다. 이 있습니까 .Any()
감자 가방에?
” 아니요 “라고 말합니다.<= false
가방을 불 속에 완전히 소각합니다. 이 있습니까 .Any()
감자는 이제 가방에?
” 가방이 없습니다 .”<= ArgumentNullException
답변
우선, 소스 코드가 ArgumentNullException
아닌 을 던질 것으로 보입니다 NullReferenceException
.
이 코드는 컬렉션이 이미 존재한다는 것을 알고있는 코드에서만 호출되기 때문에 많은 경우에 컬렉션이 null이 아님을 이미 알고 있으므로 null 검사를 자주 할 필요는 없습니다. 그러나 그것이 존재하는지 모른다면, 전화하기 전에 확인하는 것이 합리적 Any()
입니다.
이 코드의 클라이언트로서 예를 들어
((int[])null).Any()
반환해야한다고 잘못 생각false
합니까?
예. 하는 질문 Any()
답변 “이 컬렉션의 요소가 포함되어 있습니까?”입니다 이 컬렉션이 존재하지 않으면 질문 자체는 무의미합니다. 존재하지 않기 때문에 어떤 것도 포함하거나 포함 할 수 없습니다.
답변
널은 요소가 아니라 누락 된 정보를 의미합니다.
null을 피하는 것이 더 넓을 수도 있습니다. 예를 들어 내장 된 빈 열거 형 중 하나를 사용하여 null 대신 요소가없는 컬렉션을 나타냅니다.
경우에 따라 null을 반환하는 경우 빈 컬렉션을 반환하도록 해당 값을 변경할 수 있습니다. (그렇지 않으면 라이브러리 메소드 (귀하의 것이 아님)가 null을 반환하면 불행히도 정상화하기 위해 래핑합니다.)
참조
https://stackoverflow.com/questions/1191919/what-does-linq-return-when-the-results-are-empty
답변
널 조건 구문 외에 ,이 문제를 완화하는 또 다른 기술이 있습니다 : 변수를 그대로 두지 마십시오 null
.
콜렉션을 매개 변수로 승인하는 함수를 고려하십시오. 함수의 목적으로 null
비어 있고 동등한 null
경우 시작 부분에 포함되지 않도록 할 수 있습니다 .
public MyResult DoSomething(int a, IEnumerable<string> words)
{
words = words ?? Enumerable.Empty<string>();
if (!words.Any())
{
...
다른 방법에서 컬렉션을 가져올 때도 동일한 작업을 수행 할 수 있습니다.
var words = GetWords() ?? Enumerable.Empty<string>();
( 빈 컬렉션 GetWords
과 같은 기능을 제어 null
하고 빈 컬렉션과 같은 경우에는 빈 컬렉션을 먼저 반환하는 것이 좋습니다.)
이제 컬렉션에서 원하는 작업을 수행 할 수 있습니다. 이것은 컬렉션이 실패 할 때 실패 할 많은 작업을 수행해야 할 때 특히 유용 null
하며 빈 열거 형을 반복하거나 쿼리하여 동일한 결과를 얻는 경우 if
조건을 완전히 제거 할 수 있습니다.
답변
이 코드의 클라이언트로서, 예를 들어 ((int []) null) .Any ()가 false를 반환해야한다고 잘못 생각합니까?
예, 단순히 C #에 있고 그 동작이 잘 정의되고 문서화되어 있기 때문입니다.
자신의 라이브러리를 만들거나 예외 문화가 다른 다른 언어를 사용하는 경우 거짓을 기대하는 것이 더 합리적입니다.
개인적으로 나는 false를 반환하는 것이 프로그램을보다 강력하게 만드는 더 안전한 접근 방법이라고 생각하지만 적어도 논쟁의 여지가 있습니다.
답변
반복되는 null 검사로 인해 성가신 경우 고유 한 ‘IsNullOrEmpty ()’확장 메서드를 만들어 해당 이름으로 String 메서드를 미러링하고 null 검사 및 .Any () 호출을 단일 호출로 래핑 할 수 있습니다.
그렇지 않으면 귀하의 질문에 대한 의견에 @ 17 of 26에 언급 된 솔루션은 ‘표준’방법보다 짧으며 새로운 null 조건부 구문에 익숙한 모든 사람에게 합리적입니다.
if(myCollection?.Any() == true)
답변
이 코드의 클라이언트로서, 예를 들어 ((int []) null) .Any ()가 false를 반환해야한다고 잘못 생각합니까?
기대에 대해 궁금하다면 의도에 대해 생각해야합니다.
null
매우 다른 것을 의미합니다 Enumerable.Empty<T>
Erik Eidt의 답변 에서 언급했듯이 null
빈 컬렉션과 빈 컬렉션 사이에는 의미에 차이가 있습니다.
그것들이 어떻게 사용되어야하는지 한 번 봅시다.
Microsoft 설계자 Krzysztof Cwalina 와 Brad Abrams가 작성한 Framework Design Guidelines : Conventions, Idioms, and the Patterns for Reusable .NET Libraries, 2nd Edition 은 다음 모범 사례를 기술합니다.
X 컬렉션 속성 또는 컬렉션을 반환하는 메서드에서 null 값을 반환하지 마십시오. 빈 컬렉션이나 빈 배열을 대신 반환하십시오.
당신이 궁극적으로 데이터베이스에서 데이터를 가져 오는하는 메소드를 호출 고려 : 당신은 빈 배열을받을 경우 또는 Enumerable.Empty<T>
이 단순히 의미 샘플 공간 즉, 당신의 결과가이다, 비어있는 빈 세트 . null
그러나이 상황에서 수신 하면 오류 상태가 됩니다.
Dan Wilson의 감자 비유와 같은 사고 방식 에서는 데이터가 비어있는 경우에도 데이터에 대한 질문을하는 것이 좋습니다. 그러나 설정이 없으면 훨씬 의미 가 없습니다 .