기본 문자열 초기화 : NULL 또는 비어 있습니까? [닫은]


130

NULL은 항상 값이 없음을 의미하고 ""또는 String.Empty는 유효한 값이라는 생각으로 문자열을 NULL로 초기화했습니다. String.Empty가 기본값으로 간주되거나 값을 나타내지 않는 코드의 최근 예를 더 많이 보았습니다. c #에 새로 추가 된 nullable 유형으로 인해 'No Value'를 나타 내기 위해 NULL을 사용하지 않고 문자열을 거꾸로 돌파하는 것처럼 보입니다.

기본 이니셜 라이저로 무엇을 사용하고 왜 사용합니까?

편집 : 답변을 기반으로 더 이상의 내 생각을 더

  1. 오류 처리 피하기 값이 null이 아니어야하는 이유는 NULL무엇입니까? 아마도 나머지 코드베이스를 통해 오류를 처리하는 대신 오류가 발생한 위치에서 오류를 식별하는 것이 더 낫습니까?

  2. null 검사 피하기 코드에서 null 검사에 지친 경우 null 검사를 추상화하는 것이 좋지 않습니까? 아마도 문자열 메서드를 NULL안전하게 감싸 줄 수 있습니까? 끊임없이 사용 String.Empty하고 시스템에 제대로 작동하지 않으면 NULL어떻게됩니까? 어쨌든 검사를 추가하기 시작 합니까?

나는 게으름에 대한 의견으로 돌아갈 수는 없습니다. DBA는 null데이터베이스 대신 ''를 사용하면 바보 같은 9 가지 방법을 사용할 수 있습니다. 나는 같은 원칙이 프로그래밍에 적용된다고 생각하고 가치를 나타내지 않고 String.Empty오히려 머리를 쓰는 사람들을 때려야 할 사람이 있어야한다 NULL.

관련 질문


'사인'? 내가 아는 Dana가되어서는 안됩니다.
vfilby

@Joel, Zim이나 GIR에 대한 단서가없는 사람들이 너무나 놀랍습니다. 그것이 순수한 선이라고 말하지는 않지만 거기에는 엄청난 유머가 있습니다.
vfilby

알고 있지만 때로는 다른 척하는 것이 재미 있습니다.
Dana the Sane

1
MVC 양식 컬렉션이나 세션 변수 에서이 문제가 발생하면 가장 유용한 것은 null을 String으로 변환하는 것이 었습니다. 속기 및 필요한 문자열 작업을 적용하십시오. 예. (item ?? String.Empty) .Trim (). ToUpper ()
sonjz

4
이것은 건설적이지 않습니까 ??
nawfal

답변:


111

"빈"과 NULL을 구별하기 위해 +1. "빈"은 "유효하지만 공백"을 의미하고 "NULL"은 "유효하지 않음"을 의미한다는 데 동의합니다.

그래서 나는 당신의 질문에 다음과 같이 대답 할 것입니다 :

예를 들어 사용자의 중간 이름과 같이 변경되거나 변경되지 않을 수있는 유효한 기본값을 원하면 비어 있습니다.

다음 코드에서 명시 적으로 값을 설정하지 않은 경우 오류가 발생하면 NULL 입니다.


11
NULL과 비어있는 것을 구별하는 것은 실제로 둘 사이에 차이가있을 때 좋습니다. 그러나 차이가없는 경우가 많으므로 동일한 것을 나타내는 두 가지 방법이 있습니다.
Greg Smalter

6
@ 그레그 : 다양성이 혼란의 가능성이 있다는 데 동의하지만, 그것은 또한 훌륭한 자산이 될 수 있습니다. 유효 값과 유효하지 않은 값을 구별하기 위해 ""또는 NULL을 작성하는 단순하고 일관된 규칙은 코드를 이해하기 쉽게 만듭니다. 그렇기 때문에 항상 "if (var)", "if (var! = NULL)"의 포인터, "if (var! = 0)"의 정수를 사용하여 부울을 테스트합니다. 그러나 그들은 내 코드를 유지하는 가난한 개발자를 돕는 추가 정보를 가지고 있습니다.
Adam Liss

32

MSDN 에 따르면 :

Empty대신 값으로 문자열을 초기화 null하면 NullReferenceException발생 가능성을 줄일 수 있습니다 .

IsNullOrEmpty()그럼에도 불구하고 항상 사용하는 것이 좋습니다.


45
예외 가능성을 줄 였다고해서 예외가 발생하지 않아야한다는 의미는 아닙니다. 코드가 존재하는 값에 의존하면 예외가 발생합니다!
rmeador

1
물론, 거기에는 논쟁의 여지가 없습니다. OTOH, 문자열을 함께 붙이면 코딩 스타일, 경험 및 상황에 달려 있다고 생각합니다.
Tomalak

이것은 주로 내가 사용하는 것을 구별하는 것입니다.
PositiveGuy

3
.NET Framework 4+ 용 IsNullOrWhiteSpace () 를 잊지 마십시오
Coops

13

왜 문자열을 초기화하고 싶습니까? 변수를 선언 할 때 변수를 초기화 할 필요가 없으며 IMO는 할당하는 값이 코드 블록의 컨텍스트에서 유효한 경우에만 수행해야합니다.

나는 이것을 많이 본다.

string name = null; // or String.Empty
if (condition)
{
  name = "foo";
}
else
{
  name = "bar";
}

return name;

null로 초기화하지 않는 것만 큼 효과적입니다. 또한 가장 자주 값을 지정하려고합니다. null로 초기화하면 값을 할당하지 않은 코드 경로를 놓칠 수 있습니다. 이렇게 :

string name = null; // or String.Empty
if (condition)
{
  name = "foo";
}
else if (othercondition)
{
  name = "bar";
}

return name; //returns null when condition and othercondition are false

null로 초기화하지 않으면 컴파일러에서 모든 코드 경로에 값이 ​​할당되지 않았다는 오류가 발생합니다. 물론 이것은 매우 간단한 예입니다 ...

마티즈


거의 모든 C # 프로그래머가 사용한다고 생각하는 Visual Studio에서 두 번째 상황 ( = null)이 없으면 정확한 이유 때문에 경고가 발생합니다. 문자열의 기본값이 null인지 여부는 중요하지 않습니다. 모든 코드 경로를 통한 할당을 보장하지 않으면 IDE (및 / 또는 기본 컴파일러 [?])가 경고를 생성한다고 가정합니다. 경고는 컴파일을 막을 수는 없지만 여전히 해결됩니다. 쉽게 해결할 수있는 경고는 프로그래머의주의를 필요로하는 다른 사람들을 난독 화하는 데 도움이 될 수 있습니다.
Code Jockey

내 지식, 첫 번째 상황은 초기화없이 완벽하게 행복 할 것이다 namenull모든 코드 경로에 값을 할당하기 때문에, (경고없이) name모든 거기 초기화 할 필요가 없습니다 -
코드 기수

8

실제로 문자열 처리 소프트웨어가 아닌 대부분의 소프트웨어의 경우 프로그램 논리는 문자열 변수의 내용에 의존하지 않아야합니다. 프로그램에서 이와 같은 것을 볼 때마다 :

if (s == "value")

기분이 나쁩니다. 이 방법에 왜 문자열 리터럴이 있습니까? 설정은 무엇입니까 s? 논리가 문자열 값에 의존한다는 것을 알고 있습니까? 작동하려면 소문자 여야한다는 것을 알고 있습니까? 이것을 사용하도록 변경하여 수정해야합니까 String.Compare? 나는 그것을 만들고 Enum파싱해야합니까?

이러한 관점에서 볼 때, 매우 간단한 코드 철학에 도달 할 수 있습니다. 가능하면 문자열 내용을 검사하지 않아도됩니다. 문자열을 비교하는 String.Empty것은 실제로 문자열 과 문자를 비교하는 특별한 경우입니다. 실제로하지 않으면하지 않는 것이 좋습니다.

이것을 알면 코드베이스에서 이와 같은 것을 볼 때 깜박이지 않습니다.

string msg = Validate(item);
if (msg != null)
{
   DisplayErrorMessage(msg);
   return;
}

우리는 그보다 더 나은 코드를 작성하기 때문에 Validate결코 반환하지 않을 것이라는 것을 알고 String.Empty있습니다.

물론 세계의 나머지 부분은 이와 같이 작동하지 않습니다. 프로그램이 사용자 입력, 데이터베이스, 파일 등을 다룰 때 다른 철학을 고려해야합니다. 혼란에 질서를 부과하는 것은 코드의 일입니다. 그 순서의 일부는 빈 문자열이 String.Empty언제 의미해야 하고 언제 의미 해야하는지 알고 null있습니다.

(내 엉덩이에서 말하지 않았는지 확인하기 위해 코드 문자열에서`String.IsNullOrEmpty '를 검색했습니다. 54 개의 모든 항목은 사용자 입력을 처리하고 Python 스크립트에서 값을 반환하며 검색된 값을 검사하는 메소드에 있습니다. 외부 API 등)


6

이것은 실제로 C # 언어의 간극입니다. 널이 될 수없는 문자열을 정의 할 방법이 없습니다. 이것은 당신이 묘사하는 것만 큼 간단한 문제를 일으켜 프로그래머는 NULL과 String.Empty가 같은 것을 의미하기 때문에 의사가 결정할 필요가없는 결정을 내립니다. 결과적으로 나중에 다른 프로그래머가 NULL과 String.Empty를 모두 처리해야 할 수 있습니다.

더 큰 문제는 데이터베이스에서 C # 문자열에 매핑되는 필드를 정의 할 수 있지만 데이터베이스 필드는 NOT NULL로 정의 될 수 있다는 것입니다. 따라서 C # 형식을 사용하여 SQL Server에서 varchar (100) NOT NULL 필드를 정확하게 나타내는 방법은 없습니다.

사양 번호와 같은 다른 언어에서도이를 허용합니다.

제 생각에는 C #에서 null을 허용하지 않는 문자열을 정의 할 수 없다는 점은 이전에 null을 허용하는 int를 정의 할 수 없었던 것만 큼 나쁩니다.

귀하의 질문에 완전히 대답하기 위해 : 기본 초기화에는 항상 빈 문자열을 사용합니다. 데이터베이스 데이터 유형의 작동 방식과 더 유사하기 때문입니다. (편집 :이 문장은 매우 불분명했습니다. NULL이 불필요한 상태 일 때 기본 초기화에 빈 문자열을 사용합니다. NULL이 불필요한 상태이면 데이터베이스 열을 NOT NULL로 설정하는 것과 같은 방식입니다. , 많은 DB 열이 NOT NULL로 설정되어 있으므로 C # 문자열로 가져올 때 문자열이 비어 있거나 값이 있지만 결코 NULL이 아닙니다. 즉, 문자열을 NULL로만 초기화합니다. null이 String.Empty의 의미와는 다른 의미를 가지고 있고, 그 경우가 일반적인 경우보다 적다는 것을 알 수 있습니다 (그러나 여기 사람들은이 경우의 정당한 예를 제시했습니다). ")


String.Empty 사용은 데이터베이스 문자열을 정의하는 방법 중 하나 와 유사합니다 . 널을 사용하여 값을 나타내지 않는 것은 널 nvarchar와 훨씬 더 일치합니다. 나는 소금을 쓸만한 가치가있는 DBA가 ''를 사용하여 가치를 나타내지 않으면 바보 같은 9 가지 방법을 강타 할 것이라고 생각합니다.
vfilby 2011

사실, 그렉, 잘못 돌아 왔어 널 (null)을 보유 할 수 없으므로 널 (NULL) 입력 가능 컬럼에 맵핑 할 수 없기 때문에 "데이터베이스 유형의 작동 방식"이 가장 적은 널 (null)이 아닌 값 유형입니다. 계약에서 모든 문자열은 모든 varchar 열에 매핑 될 수 있습니다.
토르 하우 겐

네 말이 맞아, 내 마지막 주장은 충분히 명확하지 않았다. 대부분의 경우 내 데이터베이스 열은 NULL이 아닙니다 (빈 문자열과 NULL의 의미 사이에 차이가 없기 때문에) .null을 저장하지 않음으로써 문자열을 유사하게 유지하려고 시도합니다.
Greg Smalter

5

때에 따라 다르지.

값이 누락되었는지 알 수 있어야합니까 (정의되지 않을 수 있습니까)?

빈 문자열이 해당 문자열 사용법에 유효한 값입니까?

둘 다 "예"라고 대답 한 경우 null을 사용하고 싶을 것입니다. 그렇지 않으면 "값 없음"과 "빈 문자열"의 차이점을 알 수 없습니다.

값이 없는지 알 필요가없는 경우 빈 문자열은 사용하는 곳마다 널 검사를 건너 뛸 수 있으므로 더 안전합니다.



3

""또는 null로 설정했습니다. 항상 String.IsNullOrEmpty를 사용하여 확인하므로 어느 쪽이든 좋습니다.

그러나 내 안의 괴짜는 적절한 가치를 갖기 전에 null로 설정해야한다고 말합니다.



2

이것이 오류 방지 기술 일 가능성이 있습니까 (권장). ""는 여전히 문자열이므로 문자열 함수를 호출하여 NULL 인 경우 예외가 발생합니까?


1
그것은 내가 일반적으로 듣는 변명입니다. 게으름처럼 들립니다. "이 값을 확인하고 싶지 않기 때문에 지름길을 택할 것입니다."
vfilby

그래, 난 동의하지 않아 오류 검사 코드의 양을 줄이는 것이 좋은 상황이있을 수도 있지만 효과가없는 함수 호출도 그다지 크지 않습니다.
Dana the Sane

2

항상로 초기화합니다 NULL.

나는 항상string.IsNullOrEmpty(someString) 가치를 확인하는 데 사용 합니다.

단순한.


1

상황에 따라 다릅니다. 대부분의 경우 문자열을 사용할 때마다 null 검사를 원하지 않기 때문에 String.Empty를 사용합니다. 코드를 훨씬 간단하게 만들고 원하지 않는 NullReferenceException 충돌이 발생할 가능성이 적습니다.

문자열이 설정되었는지 여부와 빈 문자열이 유효한 위치를 알아야 할 때만 문자열을 null로 설정했습니다. 실제로 이러한 상황은 드물다.


1

빈 문자열은 값 (실수로 문자를 포함하지 않는 텍스트)입니다. Null은 값이 없음을 나타냅니다.

의도가 가치가없는 경우 변수가 실제 값을 가리 키거나 포함하지 않음을 나타내려면 변수를 null로 초기화합니다.


1

Tomalak 응답을 반복하면 문자열 변수를 초기 값 null에 할당 할 때 변수는 더 이상 문자열 객체가 아닙니다. C #의 모든 개체와 동일합니다. 따라서 변수에 대한 메소드 또는 특성에 액세스하려고 시도하고 변수가 문자열 오브젝트라고 가정하면 NullReferenceException 예외가 발생합니다.


1

널은 값이 선택적인 경우에만 사용해야합니다. 값이 선택 사항이 아닌 경우 (예 : 'Name'또는 'Address') 값은 널이 아니어야합니다. 이는 POCO 및 사용자 인터페이스뿐만 아니라 데이터베이스에도 적용됩니다. Null은 "이 값은 선택 사항이며 현재는 없습니다"를 의미합니다.

필드가 선택 사항이 아닌 경우 빈 문자열로 초기화해야합니다. null로 초기화하면 객체가 유효하지 않은 상태가됩니다 (자체 데이터 모델에 의해 유효하지 않음).

개인적으로 문자열은 기본적으로 null을 허용하지 않지만 "string?"을 선언하면 null이 가능합니다. 더 깊은 수준에서는 이것이 가능하지 않거나 논리적 인 것은 아니지만; 확실하지 않다.



0

할당되지 않은 (또는이 위치에서 프로그램 흐름이 발생하지 않는) 값으로 null을 사용하지 않는 이유는 없다고 생각합니다. 구별하려면 == null이 있습니다. 특정 값을 확인하고 null인지 다른지 상관하지 않으면 String.Equals ( "XXX", MyStringVar)가 잘 작동합니다.

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