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


41

확장 메소드를 만들 때 물론 호출 할 수 있습니다 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합니까?


40
C # 6에서 if (myCollection? .Any () == true)
17 of 26

5
다른 .NET 언어와의 상호 운용성을 제외하고 실제로 null을 사용하지 않는 F #에서도 null |> Seq.isEmptythrow를 발생 System.ArgumentNullException: Value cannot be null시킵니다. 존재할 것으로 예상되는 것에 대해 정의되지 않은 값을 전달하지 않을 것으로 예상되므로 null이있을 때 여전히 예외입니다. 초기화 문제라면, 대신 빈 시퀀스로 시작합니다 null.
Aaron M. Eshbach

21
그래서 null컬렉션을 다룰 때 돌아 가지 말고 대신 빈 컬렉션을 사용해야합니다.
Bakuriu

31
왜 처음에는 null입니까? null이 비어 있지 않기 때문에 null로 계산하지 않으려면 완전히 다른 것입니다. 어쩌면 당신의 경우에는 빈 것으로 계산되기를 원하지만 언어에 그런 종류를 추가하면 버그가 발생합니다.
user253751

22
나는 것을 지적한다 매일 LINQ 방법은 널 인수에 발생합니다. Any일관성이 있습니다.
Sebastian Redl

답변:


157

5 개의 감자가 담긴 가방이 있습니다. 이 있습니까 .Any()감자 가방에?

" "라고 말합니다.<= true

나는 모든 감자를 꺼내 먹습니다. 이 있습니까 .Any()감자 가방에?

" 아니요 "라고 말합니다.<= false

가방을 불 속에 완전히 소각합니다. 이 있습니까 .Any()감자는 이제 가방에?

" 가방이 없습니다 ."<= ArgumentNullException


3
그러나 가방 안에 감자가 없습니까? False는 False를 의미합니다 ... (나는 동의하지 않고 두 번째 관점).
D. Ben Knoble

6
더 실제적으로, 누군가가 알려지지 않은 출처에서 닫힌 상자를 건네줍니다. 상자 안의 가방에 감자가 들어 있습니까? 나는 두 가지 시나리오에만 관심이 있습니다-A) 상자에 감자가 들어있는 상자가 있거나 B) 상자에 감자가 없거나 가방이 없습니다. 의미 적으로, 예, null과 비어있는 것에는 차이가 있지만 99 %는 신경 쓰지 않습니다.
dave thieben

6
당신은 5 개의 생 감자를 먹었습니까? 즉시 의사의 진료를 받으십시오.
Oly

3
@Oly Dan은 그 불을 먹고 소각하기 전에 불에서 요리했습니다.
Ismael Miguel

3
@ D. BenKnoble : 내 차 트렁크를 보지 않고 내 차 트렁크에 시체가 없다는 것을 기꺼이 증언 하시겠습니까? 아니? 트렁크 확인과 아무것도 찾지 못하거나 트렁크를 확인하지 않는 것의 차이점은 무엇입니까? 두 경우 모두 정확히 같은 양의 시체를 보았으므로 지금 증언 할 수 없습니까? ... 차이점입니다. 처음에 실제로 확인할 수 없으면 무언가를 보증 할 수 없습니다. 당신은 두 사람이 동일하다고 가정하지만, 그것은 주어진 것이 아닙니다. 어떤 경우에는이 둘 사이에 중요한 차이가있을 수 있습니다.
Flater

52

우선, 소스 코드가 ArgumentNullException아닌 을 던질 것으로 보입니다 NullReferenceException.

이 코드는 컬렉션이 이미 존재한다는 것을 알고있는 코드에서만 호출되기 때문에 많은 경우에 컬렉션이 null이 아님을 이미 알고 있으므로 null 검사를 자주 할 필요는 없습니다. 그러나 그것이 존재하는지 모른다면, 전화하기 전에 확인하는 것이 합리적 Any()입니다.

이 코드의 클라이언트로서 예를 들어 ((int[])null).Any()반환해야한다고 잘못 생각 false합니까?

예. 하는 질문 Any()답변 "이 컬렉션의 요소가 포함되어 있습니까?"입니다 이 컬렉션이 존재하지 않으면 질문 자체는 무의미합니다. 존재하지 않기 때문에 어떤 것도 포함하거나 포함 할 수 없습니다.


18
@ChrisWohlert : 직감에 흥미가 있습니다. 의미 적으로 존재하지 않는 사람은 이름이 빈 줄이고 나이가 0 인 빈 사람이라고 생각합니까? 그리고 포함 null하는 집합이 빈 집합을 포함하는 집합과 동일 하다고 생각 합니까?
ruakh

17
@ChrisWohlert : 분명히 세트는 빈 세트를 포함 할 수 있습니다. 하지만 당신은 그렇게 생각하는 것 { null }{ {} }동등해야한다. 나는 그 매혹적인 것을 발견한다; 나는 전혀 관련이 없습니다.
ruakh

9
해야 .AddA의 null컬렉션을 어떻게 든 너무 우리를 위해 컬렉션을 만들?
Matthew

13
@ChrisWohlert "A는 빈 세트는 B가 수박을 포함하는 설정됩니다 A는 비어 예입니다 B는 비우 호입니다 C 비우 있자나 .....?.?"
user253751

16
Pedantic point : 세트 이론에서 존재하지 않는 세트가 빈 세트 인 경우는 아닙니다. 빈 세트가 존재하고 존재하지 않는 세트는 존재하지 않습니다 (실제로 존재하지 않기 때문에 전혀 존재하지 않습니다).
James_pic

22

널은 요소가 아니라 누락 된 정보를 의미합니다.

null을 피하는 것이 더 넓을 수도 있습니다. 예를 들어 내장 된 빈 열거 형 중 하나를 사용하여 null 대신 요소가없는 컬렉션을 나타냅니다.

경우에 따라 null을 반환하는 경우 빈 컬렉션을 반환하도록 해당 값을 변경할 수 있습니다. (그렇지 않으면 라이브러리 메소드 (귀하의 것이 아님)가 null을 반환하면 불행히도 정상화하기 위해 래핑합니다.)

참조 https://stackoverflow.com/questions/1191919/what-does-linq-return-when-the-results-are-empty


1
그렇다고 현명한 규칙을 사용하는 요소없다는null 것은 아닙니다 . 그냥 실제로 네이티브 OLESTRINGS, 생각 하지 않습니다 것을 의미한다.
중복 제거기

1
@ 중복 제거기, Microsoft의 Object Linking 및 Embedding perchance에 대해 이야기하고 있습니까? OLE가 90 년대에 왔다는 것을 기억하자. 현재보다 많은 현대 언어 (C #, Java, Swift)는 null의 사용을 제거 / 제거하는 기능을 제공하고 있습니다.
Erik Eidt

2
@ErikEidt 그들은 null"정보 누락"을 의미하지 않기 때문에 부분적으로 그렇게하고 있습니다. null의미있는 해석이 하나도 없습니다. 대신, 그것은 당신이 그것을 취급하는 방법의 문제입니다. null"정보 누락", "요소 없음", "오류가 발생 했음"또는 "초기화되지 않은"또는 "정보 충돌"또는 임의의 임시 작업에도 사용됩니다.
Derek Elkins

-1. 이것은 추상 이론이 아니라 개발자가 내린 결정입니다. null"데이터 없음"을 의미하는 데 절대적으로 자주 사용됩니다. 때로는 의미가 있습니다. 다른 때는 아닙니다.
jpmc26

13

널 조건 구문 외에 ,이 문제를 완화하는 또 다른 기술이 있습니다 : 변수를 그대로 두지 마십시오 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조건을 완전히 제거 할 수 있습니다.


12

이 코드의 클라이언트로서, 예를 들어 ((int []) null) .Any ()가 false를 반환해야한다고 잘못 생각합니까?

예, 단순히 C #에 있고 그 동작이 잘 정의되고 문서화되어 있기 때문입니다.

자신의 라이브러리를 만들거나 예외 문화가 다른 다른 언어를 사용하는 경우 거짓을 기대하는 것이 더 합리적입니다.

개인적으로 나는 false를 반환하는 것이 프로그램을보다 강력하게 만드는 더 안전한 접근 방법이라고 생각하지만 적어도 논쟁의 여지가 있습니다.


15
그 '견고성'은 종종 환상입니다. 버그 또는 기타 문제로 인해 배열을 생성하는 코드가 갑자기 NULL을 생성하기 시작하면 '견고한'코드가 문제를 숨길 수 있습니다. 때때로 적절한 동작이지만 안전한 기본값은 아닙니다.
GoatInTheMachine

1
@GoatInTheMachine-안전한 기본값에 동의하지 않지만 문제를 숨기고 때로는 그러한 행동이 바람직하지 않다는 것이 옳습니다. 내 경험상 문제를 숨기거나 다른 코드의 문제를 포착하기 위해 단위 테스트를 신뢰하는 것은 예기치 않은 예외를 throw하여 앱을 충돌시키는 것보다 낫습니다. 실제로 호출 코드가 null로 전송하기에 충분하지 않은 경우 예외를 올바르게 처리 할 가능성은 무엇입니까?
Telastyn

10
내 코드, 다른 동료 또는 고객의 코드가 무엇이든 문제가 발생하면 코드가 즉시 실패하고 사람들은 코드가 불일치 한 상태로 결정되지 않은 시간 동안 수행 된 것보다 코드에 대해 알았습니다. 이 작업을 수행 할 수있는 것은 물론 고급 스러우며 항상 적절하지는 않지만 내가 선호하는 접근 방식입니다.
GoatInTheMachine

1
@GoatInTheMachine-많은 것에 동의하지만 컬렉션이 다른 경향이 있습니다. null을 빈 컬렉션으로 취급하는 것은 몹시 일관성이 없거나 놀라운 동작이 아닙니다.
Telastyn

8
웹 요청을 통해 수신 된 JSON 문서에서 채워진 배열이 있고 프로덕션에서 API 클라이언트 중 하나가 갑자기 일부 JSON을 통해 배열을 NULL로 직렬화 해제하는 문제가 발생한다고 가정 해보십시오. 최악의 경우, 코드는 첫 번째 잘못된 요청이 들어온 순간 NULL 참조 예외를 발생 시켰습니다. 로깅에서 확인한 다음 즉시 클라이언트에게 깨진 요청을 수정하도록 지시하거나 코드에 "오, 배열이 비어 있습니다. 할 것!" 그리고 몇 주 동안 데이터베이스에 '구매 바구니에 품목이 없습니다'라고 조용히 썼습니까?
GoatInTheMachine

10

반복되는 null 검사로 인해 성가신 경우 고유 한 'IsNullOrEmpty ()'확장 메서드를 만들어 해당 이름으로 String 메서드를 미러링하고 null 검사 및 .Any () 호출을 단일 호출로 래핑 할 수 있습니다.

그렇지 않으면 귀하의 질문에 대한 의견에 @ 17 of 26에 언급 된 솔루션은 '표준'방법보다 짧으며 새로운 null 조건부 구문에 익숙한 모든 사람에게 합리적입니다.

if(myCollection?.Any() == true)

4
?? false대신에 사용할 수도 있습니다 == true. 의 경우 처리하기 때문에 좀 더 명시 적 (깨끗한) 것처럼 보이며 null실제로 더 이상 장황하지 않습니다. ==부울에 대한 플러스 검사는 일반적으로 내 개그 반사를 트리거합니다. =)
jpmc26

2
@ jpmc26 : 나는 C #에 대해 많이 모른다. 왜 myCollection?.Any()충분하지 않습니까?
Eric Duminil

6
@EricDuminil null 조건부 연산자가 작동하는 방식 때문에 myCollection?.Any()일반 부울 (즉, bool 대신 bool?) 대신 nullable-Boolean을 효과적으로 반환합니다. bool에서 암시 적 변환이 없습니까? bool에 대한 것으로,이 특정 예에서 ( if조건의 일부로 테스트하기 위해) 필요한 bool 입니다. 따라서 truenull 응집 연산자 (??) 와 명시 적으로 비교 하거나 사용해야합니다.
Steven Rands

트윗 담아 가기 false는 myCollection? .Any () == true를 읽기가 더 어렵습니다. 개그 반사에 관계없이 == true는 암시 적으로 테스트하려는 것입니다. ?? false는 단지 추가 노이즈를 추가하고 null이 발생하는 경우에 대해 머리에서 평가를 수행해야합니다 .null == true가 실패하면 독자가을 인식하지 않아도됩니다 ?..
Ryan The Leach

2
==실제로 작동 하는지에 대해 더 열심히 생각해야합니다 . 부울이 true또는 로만 가능할 때 직관적으로 부울이 어떻게되는지 알고 있습니다 false. 나는 그것에 대해 생각할 필요조차 없습니다. 그러나 null믹스에 버리 십시오. 이제 올바른지 여부를 해결해야합니다 ==. ??대신 null사례를 제거하여 이미 알고있는 trueand로 다시 축소합니다 false. 내 개그 반사에 관해서는, 처음 볼 때 내 직감은 일반적으로 쓸모가 없기 때문에 삭제하는 것입니다.
jpmc26

8

이 코드의 클라이언트로서, 예를 들어 ((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의 감자 비유와 같은 사고 방식 에서는 데이터가 비어있는 경우에도 데이터에 대한 질문을하는 것이 좋습니다. 그러나 설정이 없으면 훨씬 의미 가 없습니다 .


1
서로 다른 의미를 갖는지 여부는 상황에 따라 크게 다릅니다. 종종, 어떤 논리가 있든 목적을 위해 그것들은 동등한 개념을 나타냅니다. 아니 항상 , 그러나 수시로.
jpmc26

1
@ jpmc26 :이 답변의 요점은 C #에 대한 지침을 코딩함으로써 서로 다른 의미를 가지고 있다고 말하는 것입니다. 원한다면 null과 empty가 동일한 곳에서 항상 올바른 코드를 작성할 수 있습니다. 그리고 어떤 경우에는 null이든 비어 있는지에 관계없이 같은 일을 할 수도 있지만 똑같은 것을 의미하지는 않습니다.
Chris

@Chris 그리고 저는 언어를 디자인 한 사람들의 코딩 지침을 요구 사항, 사용중인 라이브러리 및 작업중인 다른 개발자의 맥락에서 코드를 평가하는 대신 사용할 수 없다고 말하고 있습니다. 그들이 문맥 상 결코 동등하지 않을 것이라는 생각은 하늘에서 가장 이상적인 이상주의입니다. 그것들은 일반적으로 현재 데이터와 동일하지 않을 수도 있지만 작성중인 특정 기능에서 결과를 생성하는 것과 동일합니다. 이 경우 두 가지를 모두 지원 해야 하지만 동일한 결과를 생성해야합니다.
jpmc26

나는 당신이 말하는 것에 혼란 스러울 수 있지만 null과 empty가 결과를 생성하는 것과 동등 할 때 왜 개별적으로 null을 사용하지 않는지 알지 못하고 한 번에 모두 수행하는 메소드를 원하기보다는 빈 검사입니다. 다른 상황에서 그들을 구별 할 수 없습니다 ...
Chris

@Chris 저는 다른 컨텍스트 (종종 범위에 해당)를 갖는 것을 말합니다. 예를 들어 기능을 고려하십시오. null및 empty는 함수에 대해 동일한 반환 값을 초래할 수 있지만 이것이 null호출 범위에서 정확히 동일한 것을 의미하는 것은 아닙니다.
jpmc26

3

이유 null와 공란이 다른 이유를 설명하는 많은 답변이 있으며 왜 그들이 다르게 취급되어야하는지 아닌지 를 설명 하려고하는 충분한 의견 이 있습니다. 그러나 당신은 묻는다 :

이 코드의 클라이언트로서, 예를 들어 ((int []) null) .Any ()가 false를 반환해야한다고 잘못 생각합니까?

그것은이다 완벽하게 합리적인 기대 . 다른 사람이 현재 행동을 옹호하는 것만 큼 옳습니다 . 나는 현재의 구현 철학에 동의하지만 추진 요인은 상황에 대한 고려를 기반으로하는 것이 아닙니다.

점을 감안 Any()조건없이 본질적으로 Count() > 0이 조각에서 무엇을 기대합니까 후?

List<int> list = null;
if (list.Count > 0) {}

또는 일반 :

List<int> list = null;
if (list.Foo()) {}

나는 당신이 기대한다고 생각합니다 NullReferenceException.

  • Any()확장 방법이므로 확장 객체 와 부드럽게 통합 해야 하며 예외를 던지는 것이 가장 놀라운 일입니다.
  • 모든 .NET 언어가 확장 방법을 지원하는 것은 아닙니다.
  • 당신은 항상 호출 할 수 있습니다 Enumerable.Any(null)그리고 거기 당신은 확실히 기대합니다 ArgumentNullException. 그것은 같은 방법이며 프레임 워크의 거의 모든 것과 일치해야합니다.
  • null객체에 접근하는 것은 프로그래밍 오류 이며, 프레임 워크는 null을 마술 값으로 강요하지 않아야 합니다 . 당신이 그런 식으로 그것을 사용하는 경우 그것을 처리하는 것은 당신의 책임입니다.
  • 그건 의견을 고집 하나의 방법을 생각하고 나는 다른 방법을 생각한다. 프레임 워크는 가능한 한 많이 의견이 맞지 않아야합니다.
  • 특별한 경우에는 일관성 이 있어야합니다 . 다른 모든 확장 방법에 대해 점점 더 많은 Count()결정을 내려야합니다. 쉬운 결정 인 것 같지 Where()않습니다. 무엇에 대해 Max()? EMPTY 목록에 대한 예외가 발생합니다. EMPTY 목록에 대해서도 예외가 발생하지 null않습니까?

LINQ 이전에 라이브러리 디자이너 null가 한 것은 유효한 값일 때 (예를 들어 String.IsNullOrEmpty()) 명시 적 방법을 도입 한 다음 기존 디자인 철학과 일치해야했습니다 . 그 경우에도 꽤 쓰기에 사소한 두 가지 방법 말했다 EmptyIfNull()EmptyOrNull()편리 할 수 있습니다.


1

짐은 모든 가방에 감자를 넣어야합니다. 그렇지 않으면 그를 죽일거야

Jim은 5 개의 감자가 담긴 가방을 가지고 있습니다. 이 있습니까 .Any()감자 가방에?

"예"라고 말합니다. <= 참

좋아, 짐은 이번에 산다.

Jim은 모든 감자를 꺼내 먹습니다. 가방에 .Any () 감자가 있습니까?

"아니요"라고 말합니다. <= 거짓

짐을 죽일 시간이야

짐은 불 속에서 가방을 완전히 소각합니다. 가방에 .Any () 감자가 있습니까?

"봉투가 없습니다." <= ArgumentNullException

짐은 살거나 죽어야합니까? 글쎄요, 우리는 이것을 기대하지 않았기 때문에 판결이 필요합니다. Jim이이 문제를 해결하도록합니까?

방법으로 주석사용 하여 널 셰넌 건을 참지 않을 수 있음을 알릴 수 있습니다.

public bool Any( [NotNull] List bag ) 

그러나 툴 체인이이를 지원해야합니다. 이는 여전히 수표를 작성하게 될 가능성이 있음을 의미합니다.


0

이것이 당신을 너무 귀찮게한다면 간단한 확장 방법을 제안합니다.

static public IEnumerable<T> NullToEmpty<T>(this IEnumerable<T> source)
{
    return (source == null) ? Enumerable.Empty<T>() : source;
}

이제 당신은 이것을 할 수 있습니다 :

List<string> list = null;
var flag = list.NullToEmpty().Any( s => s == "Foo" );

... 그리고 플래그가로 설정됩니다 false.


2
쓰기보다 자연 return으로 문을 :return source ?? Enumerable.Empty<T>();
Jeppe의 Stig 닐슨

이 질문에 대답하지 않습니다.
Kenneth K.

@ KennethK.하지만 제시된 문제를 해결하는 것 같습니다.
RQDQ

0

이것은 C #의 확장 방법과 디자인 철학에 대한 질문 이므로이 질문에 대답하는 가장 좋은 방법 은 확장 방법의 목적에 대한 MSDN 설명서 를 인용 하는 것입니다 .

확장 메서드를 사용하면 새로운 파생 형식을 만들거나 다시 컴파일하거나 원래 형식을 수정하지 않고도 기존 형식에 메서드를 "추가"할 수 있습니다. 확장 메서드는 특별한 종류의 정적 메서드이지만 확장 형식의 인스턴스 메서드 인 것처럼 호출됩니다. C #, F # 및 Visual Basic으로 작성된 클라이언트 코드의 경우 확장 메서드와 실제로 형식에 정의 된 메서드를 호출하는 것 사이에는 분명한 차이가 없습니다.

일반적으로 확장 방법을 필요한 경우에만 드물게 구현하는 것이 좋습니다. 가능하면 기존 유형을 확장해야하는 클라이언트 코드는 기존 유형에서 파생 된 새 유형을 작성하여 수행해야합니다. 자세한 내용은 상속을 참조하십시오.

확장 방법을 사용하여 소스 코드를 변경할 수없는 유형을 확장 할 때 유형 구현 변경으로 인해 확장 방법이 중단 될 위험이 있습니다.

주어진 유형에 대해 확장 메소드를 구현하는 경우 다음 사항을 기억하십시오.

  • 확장 메서드는 형식에 정의 된 메서드와 동일한 서명이 있으면 호출되지 않습니다.
  • 확장 방법은 네임 스페이스 수준에서 적용됩니다. 예를 들어이라는 단일 네임 스페이스에 확장 메서드가 포함 된 여러 정적 클래스가있는 Extensions경우 모두 using Extensions;지시문에 의해 범위에 포함됩니다 .

요약하면, 확장 메소드는 개발자가 직접 수행 할 수없는 경우에도 특정 유형에 인스턴스 메소드를 추가하도록 설계되었습니다. 또한 인스턴스 메서드는 확장 메서드가있는 경우 항상 확장 메서드를 재정의 하므로 (인스턴스 메서드 구문을 사용하여 호출 한 경우) 메서드를 직접 추가하거나 클래스를 확장 할 수없는 경우 에만 수행해야합니다. *

다시 말해서, 확장 메소드는 일부 클라이언트에 의해 인스턴스 메소드가 될 수 있기 때문에 인스턴스 메소드처럼 작동해야합니다. 그리고 호출되는 객체가 인 경우 인스턴스 메소드는 throw null해야하므로 확장 메소드도 마찬가지입니다.


* 부수적으로, 이것은 LINQ의 설계자가 직면 한 상황과 정확히 일치합니다. C # 3.0이 출시되었을 때 컬렉션과 루프 모두에서 System.Collections.IEnumerableand 를 사용 하고있는 수백만 명의 클라이언트가 이미있었습니다 . 이러한 클래스는 반환 단지 두 가지 방법이 있었다 객체 와 너무 같은 추가 요구 인스턴스 메소드 추가, , , 등, 고객의이 수백만을 깨는 것입니다. 그래서, (이 측면에서 구현 될 수 특히 이후이 기능을 제공하기 위해 와 상대적으로 쉽게), 그들은 어떤 현재 기존에 적용 할 수있는 확장 방법으로 그것을 발표System.Collections.Generic.IEnumerable<T>foreachIEnumeratorCurrentMoveNextCountAnyCurrentMoveNextIEnumerable더 효율적인 방법으로 클래스에 의해 구현 될 수도 있습니다. C #의 디자이너가 첫 날에 LINQ를 출시하기로 결정했다면이 인스턴스는의 인스턴스 메소드로 제공 IEnumerable되었을 것이며 아마도 해당 메소드의 기본 인터페이스 구현을 제공하는 일종의 시스템을 설계했을 것입니다.


0

여기서 중요한 점은 예외를 던지는 대신 false를 반환하면 코드의 미래 독자 / 수정 자와 관련이있을 수있는 정보를 모호하게 만드는 것입니다.

목록이 null 일 수 있다면 나중에 별도의 논리 경로를 사용하는 것이 좋습니다. 그렇지 않으면 나중에 누군가가 목록의 논리 (추가와 같은)를 if의 else {}에 추가 할 수 있습니다. 그들이 예측할 이유가 없다는 원치 않는 예외.

가독성과 유지 관리 성은 항상 '추가 조건을 작성해야합니다'보다 우월합니다.


0

일반적으로, 나는 대부분의 코드를 작성하여 호출자가 널 데이터를 전달하지 않을 책임이 있다고 가정합니다. 대부분의 말은 Null (및 기타 유사한 게시물)에 설명되어 있습니다. 널 (null)의 개념은 종종 잘 이해되지 않으므로 이러한 이유로 변수를 미리 가능한 빨리 초기화하는 것이 좋습니다. 합리적인 API로 작업한다고 가정하면 null 값을 반환하지 않는 것이 이상적이므로 null을 확인하지 않아도됩니다. 다른 답변에서 언급했듯이 null의 요점은 계속하기 전에 유효한 개체 (예 : "가방")가 있는지 확인하는 것입니다. 이것은 Any의 기능이 아니라 언어 의 기능입니다.그 자체. null 객체는 존재하지 않기 때문에 대부분의 작업을 수행 할 수 없습니다. 차를 소유하지 않은 경우를 제외하고는 내 차에있는 가게로 운전하라고 요청하는 것과 같습니다. 따라서 차를 사용하여 가게에 갈 방법이 없습니다. 말 그대로 존재하지 않는 작업을 수행하는 것은 무의미합니다.

요청한 정보를 문자 그대로 사용할 수없는 경우와 같이 null을 사용하는 실질적인 경우가 있습니다 (예 : 나이가 얼마인지 물었을 때이 시점에서 대답 할 가능성이 가장 높은 것은 "모름입니다" ", 이것은 null 값입니다). 그러나 대부분의 경우 변수가 초기화되었는지 여부를 최소한 알아야합니다. 그리고 그렇지 않으면 코드를 강화해야합니다. 모든 프로그램이나 함수에서 가장 먼저하는 일은 사용하기 전에 값을 초기화하는 것입니다. 변수가 null이 아닌 것을 보장 할 수 있기 때문에 null 값을 확인해야하는 경우는 거의 없습니다. 들어가는 것이 좋은 습관이며 변수를 초기화하는 것을 자주 기억할수록 null을 덜 자주 검사해야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.