Any () * not *이 null 참조 예외를 발생시킬 것으로 예상하는 것은 부당한가요? 만들 때 물론 호출

확장 메소드를 만들 때 물론 호출 할 수 있습니다 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 CwalinaBrad Abrams가 작성한 Framework Design Guidelines : Conventions, Idioms, and the Patterns for Reusable .NET Libraries, 2nd Edition 은 다음 모범 사례를 기술합니다.

X 컬렉션 속성 또는 컬렉션을 반환하는 메서드에서 null 값을 반환하지 마십시오. 빈 컬렉션이나 빈 배열을 대신 반환하십시오.

당신이 궁극적으로 데이터베이스에서 데이터를 가져 오는하는 메소드를 호출 고려 : 당신은 빈 배열을받을 경우 또는 Enumerable.Empty<T>이 단순히 의미 샘플 공간 즉, 당신의 결과가이다, 비어있는 빈 세트 . null그러나이 상황에서 수신 하면 오류 상태가 됩니다.

Dan Wilson의 감자 비유와 같은 사고 방식 에서는 데이터가 비어있는 경우에도 데이터에 대한 질문을하는 것이 좋습니다. 그러나 설정이 없으면 훨씬 의미 가 없습니다 .