문자열의 요점은 무엇입니까?


35

왜 그 부동산 string foo = string.Empty이 BCL에 포함 되었습니까? 빈 문자열 ( string foo = "")을 사용하는 것보다 더 장황하고 명확하지 않은 것처럼 보입니다.


6
Nitpick : 언어의 일부가 아닙니다. BCL의 일부입니다. VB.NET 및 F #은 다른 모든 .NET 언어와 함께 사용할 수 있습니다.
오디드

19
그렇지 않으면, 당신은 typeof(string).GetField("Empty").SetValue(null, " ");;) 같은 악한 일을 할 수 없었기 때문에
Mason Wheeler

1
@MasonWheeler-반성의 기쁨. 진정한 악의 경우, 내성 검사가 필요합니다.
Oded

1
@MasonWheeler, +1 세상에, 고글, 그들은 아무것도하지 않는다!]
Machado

1
@MasonWheeler 순수하고 증류 된 악입니다. 나는 이것을 좋아한다. 관심이 있다면 질문하십시오 public static string Empty { get { return string.Intern(""); } }.
Jesse C. Slicer

답변:


55

나는 여기서 만 가정 할 수 있습니다.

string.Empty명확성을 위해 정의되었습니다-문자열을 초기화 할 때 ""실제로 테스트 중 자리 표시 자 대신 null또는 말 " "그대로 초기화 자로 의미 된 컨텍스트에서 명확하지 않을 수 있습니다 . 사용 string.Empty은 그런 종류의 수수께끼에 대한 확실한 대답입니다.

C에 대한 되돌림이 될 수도 있습니다. C의 빈 문자열은 빈 문자열이 아닙니다. 첫 번째 문자가 null (따라서 비어 있음)이며 C #과 동일하지 않은 문자 배열입니다. 여기서 내 요점은 다른 언어로 당신은 다른 방식으로 빈 문자열을 나타내고 (다른 의미를 가질 수 있음) string.Empty그러한 모호성을 배제 한다는 것 입니다.

다른 객체가 여러 객체에 대해 말하는 것과는 달리-문자열 리터럴이 컴파일 될 때 문제가되지 않습니다. 여기에는 string.Empty- 값이 포함됩니다 "". 이들 중 하나가 코드에서 반복 될 때마다 객체는 인턴 풀에서 검색됩니다. 이는 앱 도메인별로 적용됩니다 .


5
지금까지 유일한 정답 인 +1.
psr

일부 언어 에는 빈 문자열 리터럴 이 없을 수도 있습니다 . 분명히 표준 파스칼 은 그렇지 않았습니다.
dan04

2
하지만 여전히, 당신이 쓰는 경우 - "C에서 빈 문자열은 빈 문자열이 아닌" "", 당신은 얻을 {'\0'}, 그래서 빈 문자열 리터럴과 정의의 다른 로터리 방식 사이에 차이가 없을 것입니다.
detly

14

나는 이것을 배운 출처를 100 % 확신하지 못하지만 그것을 사용하는 몇 가지 요점은 다음과 같습니다.

  • .NET 어셈블리의 각 문자열은 고유하므로

    string foo = "";
    string bar = "";
    

    문자열은 변경할 수 없으므로 출력 어셈블리에서 2 개의 문자열이됩니다. 두 참조가 모두 있으면 string.Empty조립품 크기가 줄어 듭니다.

  • 명백 함. 당신이 건너 때 string.Empty의도가 빈 문자열을해야하는데 분명하다. 그러나 foo = ""프로그래머가 테스트하는 동안 문자열의 내용을 제거하고 다시 추가하는 것을 잊었습니까? 아니면 그렇게해야합니까?

1
두 개의 동일한 문자열을 메모리에 유지하는 것은 이상한 동작으로 보입니다. 실제로 그 일은 무엇입니까?
Rig

36
실제로는 반대입니다. 문자열 인터 닝 (더 정확하게 말하면 리터럴의 인터 닝)입니다. Java와 Python에서 수행되었다는 것을 알고 있으며 .NET 언어에서도 마찬가지입니다. 물론 이것은 단일 변환 단위의 범위에서만 발생할 수 있으므로 동적 로더가 이러한 데이터를 통합하지 않으면 프로그램 파일 당 하나의 빈 문자열로 끝날 수 있습니다. 여전히별로 많지 않습니다.

9
@delnan은 절대적으로 맞습니다. ""/ string.Empty가 삽입되고 하나의 객체 만 생성됩니다.
Oded

11
@Andy-모든 문자열 리터럴 은 .NET에 저장됩니다. 모든 문자열이 아닙니다 . 프로그래밍 방식으로 생성 된 문자열은 기본적으로 인턴되지 않습니다. MSDN의 String.Intern 을 참조하십시오 .
오디드

3
@Oded et alia : 실제로 여러분 중 누구도 정확히 맞지 않습니다. 먼저 리터럴은 어셈블리 내에서 삽입 되지만 어셈블리 전체에서 반드시 필요한 것은 아닙니다 . 둘째, 빈 문자열이 어셈블리에서 인턴되는지 여부는 구현 세부 사항입니다. 일부 버전의 CLR은 그렇지 않은 버전도 있습니다. 다른 답변 중 하나에이 사실에 대한 내 기사에 대한 링크가 있습니다. 자세한 내용은 참조하십시오.
Eric Lippert

2

에 대한 객체가 생성되지 않습니다 string.Empty. 를 사용 ""하면 문자열 인턴 풀에서 오는 객체가 만들어집니다.

과거에는 사람들이 테스트를 실행 String.Empty하고 약간 더 빨리 나왔지만 미세 최적화되었습니다.

String.Empty는 다음과 같습니다.

//The Empty constant holds the empty string value.   
//We need to call the String constructor so that the compiler doesn't mark 
//this as a literal.   
//Marking this as a literal would mean that it doesn't show up as a field 
//which we can access from native.  
public static readonly String Empty = ""; 

2
그래서 요점은 ...?

1
요점은 String.Empty는 기본적으로 ""에 대한 상수입니다. 더 깊은 의미를 가진 String.cs의 저자를 찾으십시오. :)
Jon Raynor

0

메모리 소비 최적화와 문자열 비교 최적화 문제입니다. 응용 프로그램에서 빈 문자열을 사용할 때마다 0 문자를 포함하는 문자열 객체를 할당합니다. 문자열 비교는 문자 별 문자 대신 참조 (포인터)를 비교하여 수행 할 수 있습니다. 이는 빈 문자열 인 경우에도 더 빠릅니다.

응용 프로그램에서 동일한 문자열을 여러 번 사용하는 경우 문자열과 함께 String.Intern ()을 호출하여 동일한 종류의 메커니즘을 사용할 수 있습니다. 그러나 각 문자열을 한 번만 사용하면 더 많은 메모리 만 사용하게됩니다.

따라서 String.Empty는 대부분의 .Net 응용 프로그램에서 수행 할 가치가있는 특수한 경우 일 뿐이므로 BCL에 통합 된 것입니다.

이 주제에 대한 자세한 내용은 Eric Lippert의 블로그 게시물을 읽는 것이 좋습니다 .

또한 그의 블로그 게시물에서 참조한 이 문서를 살펴 봐야 합니다.


4
답변 만 링크로 응답하지 않습니다. Eric이 블로그를 재구성하면이 답변이 쓸모 없게됩니다. 제발 요약 우리가 손에 대한 모든 정보를 가지고, 그래서 여기에 게시물을.
ChrisF

7
@ChrisF : 블로그를 재구성 할 수 없습니다. 그것은 획기적인 변화 일 것입니다. 그리고 당신은 내가 그것에 대해 어떻게 느끼는지 압니다.
Eric Lippert

1
@EricLippert-나는 당신이 그렇게 하지 않을 것이라는 것을 알고 있지만 링크 만 답변이 좋은 답변이 아니며 사람들이 그것을 깨닫도록 격려해야합니다.
ChrisF

3
@EricLippert 단순한 임시 링크가 아닙니다. 또한 독자에게 공손함에 관한 것입니다. 독자가 링크를 따를 지 여부에 대한 의견을 작성할 수 있도록 답변에 직접 충분한 내용이 있어야합니다. 그리고 SE의 오프라인 사본에서도 대답이 의미가 있습니다.
Gilles 'SO- 악마 그만'
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.