2010-07-19 3 views
10

방금 ​​속성을 nullable로 선언하는 것이 유용 할 수 있다는 것을 알았던 구성 요소에 쓰기 시작했습니다. 대신 기본 값을 사용하는 것이 좋습니다. 그러나 전에는 non-nullable-type? 구문이나 Nullable<T> 유형을 사용하지 못했기 때문에 곧 뛰어 올라 나와 물지 않는 일부 문제가 있음을 알았습니다. Nullable<T> 및 약식 ? 구문을 사용 그래서 ...Nullable을 사용할 때의 Gotchas <T> C# 4

  • 가장 큰 개는 무엇인가?

  • 어떻게 해결할 수 있습니까?

  • 내가 사용하기 시작할 때 가장 큰 장점/새로운 가능성은 무엇입니까?

변수가

당신이

myvar = nullablevar ?? defaultvalue; //will set defaultvalue if nullablevar is null 

등을 할 수있는 null의 경우 사용자가 점검 할 수 .HasValue을 할 수

+9

사용하여. 그것이 터지면 다시 오십시오. 그것은 로켓 과학이 아닙니다. –

+3

@ 한스, 나는 동의하지 않는다 : 문제를 예상하려고 시도하는 것은 나쁜 일이 아니다 ... 나는 대답이 많은 사람들에게 유용 할 것이라고 확신한다. –

+0

@Closers : 나는 지역 사회로 돌아와야한다는 것을 깨닫는다. "진짜"문제가 생겼을 때이 개념이 완전히 새로운 개념이기 때문에 지형을 정찰하는 데 도움이되지는 않을 것이라고 생각했습니다. 이 개념이 그리 어렵지 않다면 어쩌면 지나치게 조심스럽게 생각할 수도 있습니다. 그러나 신기한 실수를 저지르는 영역 중 하나 일 수 있으며 어디에 위치하기가 어려울 수도 있습니다. 마크 바이어스 (Mark Byers)의 대답은 제가 찾고 있었던 훌륭한 사례입니다. –

답변

18

일반적인 잡았다가 조건부 표현식을 가진 null 가능한 변수에 다음과 같이 할당하려고 시도하고 있습니다. 그것은 작동해야처럼 언뜻

bool useDefault = true; 
int defaultValue = 50; 
int? y = useDefault ? defaultValue : null; 

이이 보일 수 있지만 실제로는 컴파일 오류가 있습니다 : 다음

 
Type of conditional expression cannot be determined because there is no 
implicit conversion between 'int' and '<null>' 

해결 방법 : 하나 또는 가능한 결과의 모두에 깁스를 추가

int? y = useDefault ? defaultValue : (int?)null; 

덜 일반적으로 볼 수 : 일반적으로는 정수 a <= 5 및에 대한 것을 가정하는 것이 안전합니다은 동일합니다. 이 가정은 null이 허용되는 정수에는 적용되지 않습니다.

int? x = null; 
Console.WriteLine(x <= 5); 
Console.WriteLine(!(x > 5)); 

결과 :

 
False 
True 

해결 방법 : 별도 널 사건을 처리합니다.


다음은 위의 다른 약간의 변화입니다 :

int? y = null; 
int? z = null; 
Console.WriteLine(y == z); 
Console.WriteLine(y <= z); 

출력 :

 
True 
False 

그래서 yz동일이지만에을하지 이하의 z.

해결 방법 : 다시, null 사례를 별도로 처리하면 놀라움을 피할 수 있습니다.

+0

엔티티 프레임 워크는 nullable 유형에 대해 많은 것을 가르쳐주었습니다. – msarchet

0

현재 4.0을 사용하고 있지는 않지만 2.0에서는 2.0을 사용하고 있습니다. 쉽게 직렬화 해제 할 수 없습니다. 리플렉션을 사용하면 4.0 버전이 더 스마트 해 지지만 기본 XML 직렬화 프로그램 유틸리티는 노출 된 버전을 읽을 수 없습니다. 그것은 꽤 성가신 일입니다.

+0

2.0에서 다른지는 알 수 없지만 XML에서 일반 유형을 serialize하는 것은 전혀 문제가되지 않습니다. ..'Foo '을 직렬화하면 XML에 ''요소가 생깁니다. –

+0

2.0에서는 일반 속성이나 필드를 사용하여 XML 디시리얼라이저에서 반사 오류가 발생합니다. List 은 serialize/deserialize를 수행하지 않기 때문에 [] 또는 ArrayList 문자열을 사용해야합니다. 4.0에서이 문제가 해결되면 내 마음이 기쁨으로 노래합니다. 레거시 코드 작업은 짜증납니다. –

0

nullable을 사용하는 동안 무의식적으로 기본값을 설정합니다. 나는 이것을 몇 번 보았다. 예 : 이 HasValue에 대한 테스트가 alwasy 사실이고 _myMemberValue 잘못 잘못된 값을 할당 할 수 있도록 값으로 초기화 때문에

int? localVar = 0; 
// do something .. 
if (localVar.HasValue) 
    _myMemberValue = localVar.Value; 

지역 변수를 결코 null입니다.

- Editied는

언급하고 잊어 버렸 ---- 더 주석을 추가 할 수 있습니다. 하나의 큰 장점은 데이터베이스에서 Nullable 필드를 나타내는 필드를 사용하는 것입니다. 이것은 또한 Linq와 EF를 사용하면 자동으로 생성됩니다. 그러나 Nullable 이전에는 일반적으로 필드의 업데이트를 처리하고 값 또는 null을 설정할 시간을 결정하는 것이 수작업이고 오류가 발생하기 쉽습니다.

1

Nullable<T>은 특수 값 유형입니다. 그것이 실제로 어떻게 작동하는지 이해한다면 도움이 될 것입니다. 그것에 대해 몇 가지 미묘한 것들이 즉시 명백하지 않습니다. 약 here에 대해 블로그를 작성했습니다.

실제 gotchas - 많지 않습니다. 가장 큰 것 중 하나는 명시 적 캐스트가 InvalidOperationException (NullReferenceException이 아님)을 던질 수 있다는 것입니다. 컴파일러가 발생할 수있는 문제를 안내해야합니다.

1

Nullable<T> 유형은 약간 특이합니다. 그들은 (엄격하게 말하면) 가치 유형이나 참조 유형은 아니지만 그 사이에 이상한 어떤 것입니다. 복싱/언 박싱 및 특히 typeof에는 특별 규칙이 있으므로 예상치 못한 결과가 발생합니다.

자세한 내용은 Jon Skeet의 서적 C# in Depth을 권장합니다. 이미 소유하고 있지 않으면해야합니다. :)

10

사람들은 종종 박스 입력 가능 값 유형과 같은 것이 없다는 것에 놀라곤합니다. 당신이 말하는 경우

int? x = 123; 
int? y = null; 
int z = 456; 
object xx = x; 
object yy = y; 
object zz = z; 

을 당신이 생각하는 ZZ는 XX와 YY는 널 (NULL)의 int를 박스 포함하는 박스 INT를 포함하기 때문이다. 그들은하지 않습니다. xx는 boxed int를 포함합니다. yy는 null로 설정됩니다.

1

가장 유용한 용도 중 하나는 nullable 데이터베이스 필드에 매핑하는 것이 가장 좋습니다. 데이터베이스의 null 필드처럼 사용하고 싶습니다.

즉, null 값은 "기타"가 아닙니다.이 값은 알 수 없거나이 시점에서 계산할 수 없거나이 개체/레코드에 다른 값이 주어진 경우 의미가 없습니다. .

actualValue = userValue.HasValue ? userValue : defaultValue; 
: - 사용자 환경 설정이 null이 될 수 있으며, 실제 값은

actualValue = userValue ?? defaultValue; 

?? 될 널 병합 연산자입니다 - 위 다음에 해당 상황이 유효처럼 들린다

또는

actualValue = (userValue != null) ? userValue : defaultValue; 

나는 사람들이 가장 자주 트라이 상태 플래그로 bool?을 사용으로 줄 참조 유혹

. true/false/???에는 세 번째 가능성이 없기 때문에 이것은 이해가되지 않습니다. 당신의 코드를 읽는 다른 사람들은 청색 텍스트를 사용하고, 거짓을 의미하는 빨간색 텍스트를 의미하고, null은 녹색 텍스트를 의미한다는 것을 알아 내기 위해 주석을 통해 파헤쳐 야합니다 (최상의 경우 시나리오). 열거를 사용하십시오. 나는 사람들이 빠질 볼 수있는 가장 큰 함정

-하여 nullables가 null의 경우 이외는, 단지 확인에 익숙해 - 중 null로 비교를 통해 또는 코드를 작성 .HasValue

+0

트라이 상태 플래그로 'bool?'에 대한 노트 = 1) –

관련 문제