null과 System.DBNull.Value의 차이점은 무엇입니까?


92

null과 System.DBNull.Value 사이에 차이점이 있습니까? 그렇다면 무엇입니까?

이제이 동작을 발견했습니다.

while (rdr.Read())
{
    if (rdr["Id"] != null) //if (rdr["Id"] != System.DBNull.Value)  
    {
        int x = Convert.ToInt32(rdr["Id"]);
    }
}

반환 값이 없지만 I는 SQL의 DataReader를 사용하여 데이터베이스에서 데이터를 검색하는 동안 if(rdr["Id"] != null)반환 true결국 정수로 널 캐스팅에 대한 예외 던졌다가.

그러나 이것은 내가 사용하면 if (rdr["Id"] != System.DBNull.Value)returns false.

null과 System.DBNull.Value의 차이점은 무엇입니까?


글쎄, 그들은 관련이 없습니다. 하나는에있는 클래스의 정적 인스턴스이고 System.Data다른 하나는 참조 대상이 없음을 나타내는 특수 값입니다. 그들은 서로 관련이 없습니다. 헷갈리는 부분에 대해 자세히 설명해 주시겠습니까? 당신의 진짜 문제인가 "하는 이유 DataRowsDataReaders넣어 DBNull.Value대신 자신의 내부는 null?"
mqp

글쎄, 처음은 아니었지만 당신이 말한 것을 배우고 나서 궁금합니다. DataRows와 DataReaders가 null 대신 DBNull.Value를 자체에 넣는 이유를 말씀해 주시겠습니까?
pavanred

나 자신을 잘 모르겠습니다. 여기에 한 가지 대답이 있습니다. stackoverflow.com/questions/4488727/what-is-the-point-of-dbnull/… nullable 값 유형이 C #에 등장하기 전에는 null.
mqp

1
여기에 답이 있었지만 stackoverflow.com/questions/4488727/what-is-the-point-of-dbnull 에 더 적합하다는 것을 깨달았습니다. 그래서 저는 그것을 옮겼습니다
Marc Gravell

답변:


117

글쎄, null어떤 유형의 인스턴스도 아닙니다. 오히려 잘못된 참조입니다.

그러나 System.DbNull.Value,의 인스턴스에 대한 유효한 참조이다 System.DbNull( System.DbNull싱글하고 System.DbNull.Value당신에게 그 클래스의 단일 인스턴스에 대한 참조 제공) 존재하지 않는 나타냅니다 *의 데이터베이스에 값을.

* 일반적으로라고 말하지만 null문제를 혼동하고 싶지는 않습니다.

따라서 둘 사이에는 큰 개념적 차이가 있습니다. 키워드 null가 잘못된 참조를 나타냅니다. 클래스 System.DbNull는 데이터베이스 필드에 존재하지 않는 값을 나타냅니다. 일반적으로 null두 개의 매우 다른 개념 (이 경우 데이터베이스 필드에 존재하지 않는 값 대 유효하지 않은 참조)을 나타 내기 위해 동일한 것을 사용하지 않도록해야합니다 (이 경우).

이것이 바로 많은 사람들 이 일반적으로 null 객체 패턴 을 사용하는 이유 System.DbNull입니다. 이것이 바로 그 예입니다.


43
+1 실용적인 예 :를 사용하면 IDbCommand.ExecuteScalar()null (레코드가 반환되지 않음) 또는 DbNull(첫 번째 레코드의 첫 번째 열이 '존재하지 않는 값'임)을 반환 할 수 있습니다 . DbNull당신이 없이는 다른 것을 구별 할 수 없을 것입니다.
C.Evenhuis 2013

Null 사용을 금지하는 언어를 사용하는 것이 좋으며 추가 비용이 전혀 들지 않습니다. 인생은 "null 개체 패턴"에 비해 너무 짧습니다
nicolas 2014 년

3
널 참조는 완벽하게 유효합니다. ☺
IllidanS4가 Monica 지원 Monica

@ C.Evenhuis 글쎄요, 또 다른 일반적인 조언이 있습니다 : 함수는 한 가지 유형의 값만 반환해야합니다. 이것이 사람들이 잘 형식화 된 TypeScript 코드를 선호하는 이유입니다. "실행 상태는 무엇입니까"는 "계산 결과는 무엇입니까"와 다릅니다. 즉. 그들은이 함수를 다른 방식으로 구현하기로 결정할 수 있습니다 (아마도 out 매개 변수이거나 HTTP 요청 응답 objs와 유사한 객체 일 수 있음). 물론 이것은 정말로 원하지 않는 합병증이지만 그들이 그렇게했다면 아마도 DbNull 대신 null을 사용할 수 있습니다.
klenium

21

DBNull 클래스 의 문서에서 :

개체 지향 프로그래밍 언어의 null 개념을 DBNull 개체와 혼동하지 마십시오. 객체 지향 프로그래밍 언어에서 null은 객체에 대한 참조가 없음을 의미합니다. DBNull은 초기화되지 않은 변형 또는 존재하지 않는 데이터베이스 열을 나타냅니다.


11

DBNull.Value는 처리해야하는 성가신 일입니다.

DBNull인지 확인한 다음 값을 반환하는 정적 메서드를 사용합니다.

SqlDataReader r = ...;
String firstName = getString(r[COL_Firstname]);

private static String getString(Object o) {
   if (o == DBNull.Value) return null;
   return (String) o;
}

또한 DataRow에 값을 삽입 할 때 "null"을 사용할 수 없으며 DBNull.Value를 사용해야합니다.

"null"의 두 가지 표현은 명백한 이점이없는 잘못된 설계입니다.


2
혐오 우리의 주 다시의 정서 : 마지막 명령문은 여기 보여주는 아이러니에 의해 날조되는이를 읽고 사용자 이름을 찾는 것은 "혐오"로
Iofacture

5

DBNull.Value는 .NET 데이터베이스 공급자가 데이터베이스의 null 항목을 나타 내기 위해 반환하는 것입니다. DBNull.Value가 null이 아니고 데이터베이스 행에서 검색된 열 값에 대한 null 비교가 작동하지 않으므로 항상 DBNull.Value와 비교해야합니다.

http://msdn.microsoft.com/en-us/library/system.dbnull.value.aspx


추신 DBNull.Value를 사용하여 데이터베이스에 널 매개 변수를 전달해야합니다. 그렇지 않으면 매개 변수가 전달되지 않은 것으로 해석 될 수 있습니다.
James Michael Hare

1
DBNull은 "데이터베이스가 반환하는 내용" 이 아니라 ADO.NET이 해석하기 위해 선택하는 방법입니다. 개인적으로 저는이 해석이 매우 가치가 있는지 잘 모르겠습니다
Marc Gravell

@MarcGravell 네, 마크, 맞습니다. 나는 그것을 잘못 말 하였다. ASP.NET은 DBNull.Value에 데이터베이스 널 (null) 열 값을 변환
제임스 마이클 토끼에게

3

DataRow에는 IsNull()데이터베이스에 표시되는 null과 관련하여 null 값이있는 경우 열을 테스트하는 데 사용할 수있는 호출되는 메서드가 있습니다.

DataRow["col"]==null항상 될 것 false입니다.

사용하다

DataRow r;
if (r.IsNull("col")) ...

대신.


3

Null은 C ++의 제로 포인터 와 유사합니다 . 따라서 어떤 값도 가리 키지 않는 참조입니다 .

DBNull.Value완전히 다르며 필드 값에 NULL이 포함 된 경우 반환 되는 상수 입니다.

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