2009-05-06 4 views
35

.net 2.0에서 소개 된 개념에 대한 좋은 지침을 찾고 있습니다.C에서 nullable 형식을 항상 사용하면 안되는 이유

왜 null이 아닌 데이터 형식을 C#으로 사용하고 싶습니까? (더 나은 질문은 기본적으로 null 입력 가능 유형을 선택하지 않고 명시 적으로 이해할 수있는 경우 nullable 유형 만 사용하는 것입니다.)

nullable 데이터 유형을 선택하는 경우 '중요한' Null을 허용하지 않는 피어?

Guid.empty, string.empty, DateTime.MinValue, < = 0 등 대신 null에 대한 내 값을 확인하고 일반적으로 null 입력 가능 유형을 사용하는 것이 훨씬 더 좋습니다. 그리고 내가 nullable 타입을 더 자주 선택하지 않는 유일한 이유는 내 머리 뒤쪽의 가려운 감각 때문이다. 문자를 사용하여 명시 적으로 null 값을 허용합니다.

항상 (항상) null 허용되지 않는 유형 대신 nullable 유형을 선택하는 사람이 있습니까? 시간에 대한

감사합니다,

+0

Jon Skeet은 구조체 인 System.Nullable에 대해 정확합니다.따라서 힙이 아니라 스택에 할당됩니다. –

+3

성능 저하에 대한 질문은 사용자가 대답 할 수만 있습니다. 당신은 고객에게 "의미있는"것이 무엇을 의미 하는지를 아는 사람입니다. 하지만 히트는 최소한이어야합니다. nullable int는 int와 null을 나타내는 bool 플래그를 더한 것과 거의 동일합니다. Nullable 형식은 int를 플래그로 패키지하는 편리한 방법입니다. –

답변

46

이유를 참조하십시오. 그리고 가능한 한 자주 이런 경우가되도록 코드를 디자인해야합니다. 값을 초기화 할 수없는 방법이 없다면 null이 값을 합법적으로 받아 들일 이유가 없습니다. 아주 간단한 예를 들어,이 사항을 고려하십시오

List<int> list = new List<int>() 
int c = list.Count; 

이 항상 유효입니다. c을 초기화 할 수없는 방법은 없습니다. int?으로 바뀌면 독자는 "이 값이 null 일 수 있습니다. 코드를 사용하기 전에 확인하십시오."라는 코드를 독자에게 효과적으로 말하게됩니다. 그러나 우리는 이것이 결코 일어날 수 없다는 것을 알고 있습니다. 그래서 코드에이 보증을 드러내지 않으시겠습니까?

값이 선택 사항 인 경우 절대적으로 적합합니다. 문자열을 반환하거나 반환하지 않을 함수가 있으면 null을 반환합니다. string.Empty()를 반환하지 마십시오. "마법의 가치"를 반환하지 마십시오.

그러나 일부 값은 선택 사항이 아닙니다. 모든 것을 선택적으로 만드는 것은 나머지 코드를 훨씬 더 복잡하게 만듭니다 (처리해야하는 다른 코드 경로를 추가합니다).

특히이 값이 항상 유효하다는 것을 보장 할 수 있다면 왜이 정보를 버리시겠습니까? 그게 당신이 그것을 nullable 타입으로 만드는 것입니다. 이제 값이 존재할 수도 있고 존재하지 않을 수도 있고, 값을 사용하는 사람은 두 경우를 모두 처리해야합니다. 그러나 당신은이 경우들 중 오직 하나만이 가능하다는 것을 알고 있습니다. 따라서 사용자가 코드를 호의적으로 사용하고 코드에이 사실을 반영하십시오. 코드를 사용하는 모든 사용자는 유효한 값에 의존 할 수 있으며 두 개가 아닌 하나의 사례 만 처리하면됩니다.

+0

이것은 정말 좋은 답변이지만 질문을 수정하려고합니다. 엔터프라이즈 응용 프로그램의 Bussiness Domain Class Properties에 항상 Nullable 형식을 사용하면 안됩니까? 나는 아마도 내가 대부분의 시간을 할 수 있다고 생각한다. 시간 내 줘서 고마워. –

+2

나는 엄지 손가락 같은 규칙이 거기에 적용된다고 생각한다. 재산이 항상 유효하다는 것을 보장 할 수 있습니까? (당신의 객체는 항상 ID를 가질 것이기 때문에 nullable을 만들지는 않는다. 그러나 객체의 상태에 따라 다른 속성들이 존재할 수도 있고 존재하지 않을 수도있다. 그러나 만약 당신이 값을 null이 아닌 값으로 만들 수 있다면, 사용자가 null에 대해 확인할 필요가 없으므로 나중에 작업하는 것이 훨씬 더 편리합니다. 속성이 유효하다는 것을 보장 할 수 있는지 확인하십시오. 그렇다면 nullable로 설정하지 마십시오. – jalf

+5

SpeC# 기능을 사용하여 참조 유형을 null이 아닌 것으로 선언하면 멋지지 않겠습니까? '문자열!'은 null이 될 수없는 문자열을 나타냅니다. –

9

는 항상 nullable 형식이 null 여부를 확인해야하는 불편 때문입니다.

분명히 값이 진정으로 선택적인 상황이있을 수 있으며, 그러한 경우에는 매직 넘버가 아닌 null 가능 유형을 사용하는 것이 합리적이지만 가능한 경우에는 피하려고 시도합니다.

// nice and simple, this will always work 
int a = myInt; 

// compiler won't let you do this 
int b = myNullableInt; 

// compiler allows these, but causes runtime error if myNullableInt is null 
int c = (int)myNullableInt; 
int d = myNullableInt.Value;  

// instead you need to do something like these, cumbersome and less readable 
int e = myNullableInt ?? defaultValue; 
int f = myNullableInt.HasValue ? myNullableInt : GetValueFromSomewhere(); 
+0

이것이 내 포인트라고 생각합니다. 잠재적으로 myNonNullableInt는 아직 설정되지 않았으며 null이 아닌 내 비즈니스 도메인에 대해 유효하지 않은 기본값 0 값을 갖습니다. 어쨌든 확인을해야합니다. 그리고 myNullableInt! = null from myNonNullableInt> 0 –

+0

로컬이 아닌 범위의 경우에도 적절한 nullable 형식을 사용하는 것이 좋습니다. 값이 실제로 null 일 수 없으면 nullable로 선언하는 이유는 모든 코드 조각을 의미합니다. 그 유형을 다루는 것은 여분의 수표 등을해야만합니다. – LukeH

0

나는 그들이 이해 곳 nullable 형식을 사용하는 경향이 -이 문제가 될 때까지 그때 나는 그것이 그것으로 할 수있는 몇 안되는 부분을 수정거야, 성능에 대해 걱정하지 않습니다.

그러나 일반적으로 대부분의 내 값은 nullable이되지 않습니다. 사실 null을 사용할 때 참조 유형과 함께 사용할 수있는 NotNullable을 사용하는 것이 좋을 때가 많습니다. 사용하지 않을 때 나중에 사용할 수 있습니다.

2

저는 언어 디자이너가 '참조 유형이 기본적으로 nullable 인 참조 유형'이 실수 였고 nullable이 유일한 현명한 기본값이라는 것을 알고 있다고 생각합니다. 널 값으로 선택해야합니다. (이것은 현대의 많은 함수 언어에서의 방법입니다.) "null"은 보통 문제의 힙입니다.

+0

당신은 언어 디자이너가 nullness로부터 "벗어나고 싶다"고 말했지만 실제로는 NULL이 될 수없는 값 유형에 null 가능성을 추가했습니다. 참조 유형은 기본적으로 여전히 null이며 옵트 아웃 할 방법이 없습니다. 나는 너의 추론을 이해하지 못한다. – Lucas

+1

다음은 일부 언어 디자이너의 위치를 ​​특성화하는 더 좋은 방법입니다. 값 유형과 참조 유형의 두 가지 유형이 있습니다. nullable 유형과 Null 허용 불가능 유형의 두 가지 유형이 있습니다. 우리는 모든 참조 유형이 nullable이고 모든 값 유형이 nullable이 아닌 유형 시스템으로 시작했습니다. 그런 다음 null 값 유형을 추가했습니다. 그러나 nullable이 아닌 참조 유형을 추가하는 것은 현재 매우 어렵습니다. 4 가지 가능성 모두를 고려하여 타입 시스템을 설계하는 것이 더 좋았을 것입니다. –

+0

예, 에릭이 한 말은 훌륭합니다. 일부 상호 운영 시나리오 (예 : SQL 데이터베이스)의 경우 값 유형에 대한 Null 허용 여부가 특정 이점입니다. 그러나 대부분의 유형에 대한 null 허용되지 않음은 일반적인 소프트웨어 엔지니어링 관점에서 대부분의 코드에 대한 일반적인 승리입니다. – Brian

3
당신은 2 개 개의 다른 질문을 갖고있는 것 같다

...

왜 내가 C#에서 null이 허용되지 않는 데이터 유형을 사용할 것

?

간단합니다. 의존하는 값 형식 데이터가 컴파일러에서 실제로 값을 갖기 때문에 간단합니다!

기본적으로 Null 허용 유형을 선택하지 않고 명시 적으로 의미가있는 경우 Null 허용 유형을 사용하지 않는 이유는 무엇입니까?

Joel은 이미 언급했듯이 유형이 참조 유형 인 경우에만 null이 될 수 있습니다. 값 유형은 컴파일러에서 값을 갖도록 보장됩니다. 프로그램이 변수를 사용하여 값을 가지면 null 허용 가능 유형을 선택하지 않아도되는 동작입니다.

물론 데이터가 프로그램이 아닌 다른 곳에서 나왔을 때 모든 베팅은 꺼져 있습니다. 가장 좋은 예는 데이터베이스입니다. 데이터베이스 필드는 null 일 수 있으므로 프로그램 변수가 "마술"값 (예 : -1, 0 또는 무엇이든)을 나타내는 것뿐만 아니라 null을 나타내는 것이 좋습니다. Null을 허용하는 유형으로이 작업을 수행합니다. null 값은 "아직 초기화되지"또는 "지정되지 않음"으로 사용하기위한 편리 할 수 ​​있지만

+0

다른 답변/설명에서 언급했듯이 null 가능 유형 *은 값 유형이지만 값을 가질 수는 없습니다. (그게 HasValue 속성이있는 곳입니다!) – LukeH

+0

"nullable이 아닌 값 유형"을 의미하는 것은 괜찮습니다. :) – Lucas

0

값은, 그들은 당신이 null의 의미를 과부하뿐만 아니라하고 주로하기 때문에, 코드가 더 복잡하게 변수 (number-or-null 대 just-a-number).

NULL 값은 많은 데이터베이스 설계자와 SQL 데이터베이스 프로그래머가 선호하지만 null 값으로 처리 할 수있는 문제에 대해 약간의 변경을 가하고 사실 간단하고 안정적인 코드를가집니다 (예 : NullReferenceException 걱정할 필요가 없음) .

실제로 "T!"라는 큰 수요가 있습니다. 참조 유형을 nullable이 아닌 연산자로 만드는 "T?"연산자와 비슷합니다. 값 유형을 nullable로 만들고 C#의 발명가 인 Anders Hejlsberg는 자신이 능력을 포함하기를 바랬습니다.

또한 질문, 당신은 항상 때로는 값 초기화됩니다 보장 할 수 있는지입니다 nullable 형식을 사용하지 말아야하는 이유 Why is “null” present in C# and java?

0

Nullable 형식을 사용해야하는 유일한 경우는 데이터베이스 테이블의 특정 필드에서 특정 시점에 응용 프로그램에서 Null을 보내거나받을 것을 절대적으로 요구하는 경우입니다. 이런 경우에도 Nullable Type을 사용하는 방법을 항상 찾아야합니다. Bool이 항상 친한 친구는 아닙니다.

관련 문제