답변:
버전 2.0 이전 .NET에서 ""
동안 객체를 생성 string.Empty
어떤 객체 생성되지 심판 하게하는, string.Empty
보다 효율적으로.
버전 2.0 이상에서 .NET의 모든 항목은 ""
수단이 동일한 문자열 리터럴을 참조 ""
에 해당 .Empty
아직도 최대한 빨리,하지만 .Length == 0
.
.Length == 0
가장 빠른 옵션이지만 .Empty
약간 더 깨끗한 코드를 만듭니다.
자세한 내용은 .NET 사양을 참조하십시오 .
string.IsNullOrEmpty( stringVar )
.
String.Empty와 ""의 차이점은 무엇이며 상호 교환 가능합니까?
string.Empty
읽기 전용 필드 인 반면 ""
컴파일 시간 상수입니다. 다르게 행동하는 장소는 다음과 같습니다.
C # 4.0 이상의 기본 매개 변수 값
void SomeMethod(int ID, string value = string.Empty)
// Error: Default parameter value for 'value' must be a compile-time constant
{
//... implementation
}
switch 문의 사례 표현
string str = "";
switch(str)
{
case string.Empty: // Error: A constant value is expected.
break;
case "":
break;
}
속성 인수
[Example(String.Empty)]
// Error: An attribute argument must be a constant expression, typeof expression
// or array creation expression of an attribute parameter type
String.Empty
대부분의 경우 인수를 인수로 전달할 수 있기 때문 입니다. 모든 예가 그 사실을 보여주는 것이 맞습니다. 바로 그 예가 보여주고 자하는 you simply can't put a (run-time) "value" into (compile-time) metadata
것입니다.
이전 답변은 .NET 1.1에 적합했습니다 (링크 된 게시물 날짜 : 2003). .NET 2.0 이상에서는 본질적으로 차이가 없습니다. JIT는 어쨌든 힙에서 동일한 객체를 참조하게됩니다.
C # 사양에 따라 2.4.4.5 섹션 : http://msdn.microsoft.com/en-us/library/aa691090(VS.71).aspx
각 문자열 리터럴이 반드시 새로운 문자열 인스턴스가 될 필요는 없습니다. 문자열 같음 연산자 (7.9.7 단원)에 따라 동등한 둘 이상의 문자열 리터럴이 동일한 어셈블리에 나타날 경우 이러한 문자열 리터럴은 동일한 문자열 인스턴스를 나타냅니다.
누군가 브래드 아브람 (Brad Abram)의 게시물에서 이것을 언급했습니다.
요약하면 ""대 String.Empty의 실제 결과는 nil입니다. JIT는 결국 그것을 알아낼 것입니다.
개인적으로 JIT가 나보다 똑똑하다는 것을 알았으므로 마이크로 컴파일러 최적화로 너무 영리하지 않도록 노력하십시오. JIT는 for () 루프를 펼치고 중복 코드, 인라인 메소드 등을 더 적절하고 적절한 시점에 I 또는 C # 컴파일러가 사전에 예상했던 것보다 더 적절한 시간에 전개합니다. JIT가 그 일을하게하십시오 :)
String.Empty
A는 읽기 전용 동안 필드 ""
A는 CONST . 이것은 String.Empty
상수가 아니기 때문에 switch 문에서 사용할 수 없음을 의미합니다 .
default
우리가없이 가독성을 홍보 할 수있는 키워드, 정직하게하지만, 난 여전히 String.Empty로 기본보다 더 읽을 생각하지만, 느린 입력, 우발적 인 변경을 방지하고, 컴파일 타임 상수가
또 다른 차이점은 String.Empty가 더 큰 CIL 코드를 생성한다는 것입니다. ""및 String.Empty를 참조하는 코드의 길이는 동일하지만 컴파일러는 String.Empty 인수에 대해 문자열 연결 (Eric Lippert의 블로그 게시물 참조)을 최적화하지 않습니다 . 다음과 같은 기능
string foo()
{
return "foo" + "";
}
string bar()
{
return "bar" + string.Empty;
}
이 IL을 생성
.method private hidebysig instance string foo() cil managed
{
.maxstack 8
L_0000: ldstr "foo"
L_0005: ret
}
.method private hidebysig instance string bar() cil managed
{
.maxstack 8
L_0000: ldstr "bar"
L_0005: ldsfld string [mscorlib]System.String::Empty
L_000a: call string [mscorlib]System.String::Concat(string, string)
L_000f: ret
}
"bar " + (ok ? "" : "error")
위의 답변은 기술적으로 정확하지만 최상의 코드 가독성과 예외 가능성을 최소화하기 위해 실제로 사용하려는 것은 String입니다.
--foo=$BAR
하는 경우 env var 설정을 잊어 버리고 플래그를 전혀 전달하지 않는 것의 차이점을 확인하고 싶을 것입니다. string.IsNullOrEmpty
입력을 올바르게 확인하지 않았거나 이상한 일을하는 코드 냄새가 종종 있습니다. 실제로 null
, 또는 Maybe / Option 유형과 같은 것을 사용할 때 빈 문자열을 허용해서는 안됩니다 .
내가 사용하는 경향 String.Empty
보다는 ""
, 하나의 간단한 아직없는 명백한 이유를 :
""
와 ""
동일하지 않습니다, 첫 번째는 실제로 16 개 제로 폭 문자가 있습니다. 유능한 개발자는 코드에 폭이 0 인 문자를 넣지 않을 것입니다. 그러나 코드에 들어가면 유지 관리가 악몽이 될 수 있습니다.
노트:
내가 사용 U + FEFF을 이 예에.
SO가 그 문자를 먹을지 확실하지 않지만 많은 0 너비 문자 중 하나를 사용하여 직접 시도하십시오.
https://codegolf.stackexchange.com/ 덕분 에이 문제에 직면했습니다.
String.Empty
보다 사용하십시오 ""
.
이것은 메모리 사용량보다 속도가 빠르지 만 유용한 팁입니다. 는
""
리터럴 그래서 리터럴 역할을 할 것이다 : 제 용도에 생성되고, 다음에 참조 용으로 반환된다.""
사용 횟수에 관계없이 하나의 인스턴스 만 메모리에 저장됩니다! 여기에 메모리 페널티가 없습니다. 문제""
는를 사용할 때마다 비교 루프가 실행되어""
이미 인턴 풀에 있는지 확인하는 것 입니다. 다른쪽에 는 .NET Framework 메모리 영역에 저장된String.Empty
참조가 있습니다 . VB.NET 및 C # 응용 프로그램의 동일한 메모리 주소를 가리 킵니다. 따라서 참조가 있을 때 필요할 때 마다 참조를 검색하는 이유는 무엇입니까?""
String.Empty
""
String.Empty
?
참조 : String.Empty
vs""
그것은 중요하지 않습니다!
이것에 대한 과거의 토론 :
http://www.codinghorror.com/blog/archives/000185.html
Eric Lippert 는 다음과 같이 썼습니다 (2013 년 6 월 17 일).
"C # 컴파일러에서 처음으로 작업 한 알고리즘은 문자열 연결을 처리하는 최적화 프로그램이었습니다. 불행히도 저는이 최적화를 Roslyn 코드베이스로 이식하지 못했습니다. " 그것을 얻으십시오! "
2019 년 1 월 현재 일부 Roslyn x64 결과 는 다음과 같습니다 .이 페이지의 다른 답변에 대한 합의 된 의견에도 불구하고, 현재 x64 JIT가 모든 사례를 말하고 완료했을 때 이러한 모든 사례를 동일하게 취급하는 것으로 보이지 않습니다.
그러나 특히이 예제 중 하나만 실제로 호출 String.Concat
하고 결과가 정확하지 않기 때문에 (최적화 감독과 달리) 추측합니다. 다른 차이점은 설명하기가 더 어려워 보입니다.
default (String) + {default (String), "", String.Empty}
static String s00() => default(String) + default(String);
mov rax,[String::Empty]
mov rax,qword ptr [rax]
add rsp,28h
ret
static String s01() => default(String) + "";
mov rax,[String::Empty]
mov rax,qword ptr [rax]
add rsp,28h
ret
static String s02() => default(String) + String.Empty;
mov rax,[String::Empty]
mov rax,qword ptr [rax]
mov rdx,rax
test rdx,rdx
jne _L
mov rdx,rax
_L: mov rax,rdx
add rsp,28h
ret
""+ {default (String), "", String.Empty}
static String s03() => "" + default(String);
mov rax,[String::Empty]
mov rax,qword ptr [rax]
add rsp,28h
ret
static String s04() => "" + "";
mov rax,[String::Empty]
mov rax,qword ptr [rax]
add rsp,28h
ret
static String s05() => "" + String.Empty;
mov rax,[String::Empty]
mov rax,qword ptr [rax]
mov rdx,rax
test rdx,rdx
jne _L
mov rdx,rax
_L: mov rax,rdx
add rsp,28h
ret
String.Empty + {default (String), "", String.Empty}
static String s06() => String.Empty + default(String);
mov rax,[String::Empty]
mov rax,qword ptr [rax]
mov rdx,rax
test rdx,rdx
jne _L
mov rdx,rax
_L: mov rax,rdx
add rsp,28h
ret
static String s07() => String.Empty + "";
mov rax,[String::Empty]
mov rax,qword ptr [rax]
mov rdx,rax
test rdx,rdx
jne _L
mov rdx,rax
_L: mov rax,rdx
add rsp,28h
ret
static String s08() => String.Empty + String.Empty;
mov rcx,[String::Empty]
mov rcx,qword ptr [rcx]
mov qword ptr [rsp+20h],rcx
mov rcx,qword ptr [rsp+20h]
mov rdx,qword ptr [rsp+20h]
call F330CF60 ; <-- String.Concat
nop
add rsp,28h
ret
Microsoft (R) Visual C# Compiler version 2.10.0.0 (b9fb1610)
AMD64 Release
[MethodImpl(MethodImplOptions.NoInlining)]
'SuppressJitOptimization' = false
Entity Framework 관점에서이 기능을 사용하면 EF 버전 6.1.3이 유효성 검사시 String.Empty와 ""를 다르게 처리하는 것으로 보입니다.
string.Empty는 유효성 검증을 위해 널값으로 처리되며 필수 (속성) 필드에서 유효성 검증 오류가 사용되면 유효성 검증 오류가 발생합니다. 여기서 ""는 유효성 검사를 통과하고 오류를 발생시키지 않습니다.
이 문제는 EF 7+에서 해결 될 수 있습니다. 참조 :-https: //github.com/aspnet/EntityFramework/issues/2610 ).
편집 : [Required (AllowEmptyStrings = true)]는이 문제를 해결하여 string.Empty의 유효성을 검사합니다.
코드를 통해 시각적으로 스캔 할 때 문자열 색상이 지정되는 방식으로 ""이 색상으로 표시됩니다. string.Empty는 일반 클래스 멤버 액세스처럼 보입니다. 간략히 살펴보면 ""를 쉽게 발견하거나 의미를 직관 할 수 있습니다.
문자열을 찾으십시오 (스택 오버플로 색상 지정은 정확히 도움이되지는 않지만 VS에서는 더 분명합니다).
var i = 30;
var f = Math.Pi;
var s = "";
var d = 22.2m;
var t = "I am some text";
var e = string.Empty;
\u00ad
.
여기의 모든 사람들은 좋은 이론적 설명을했습니다. 나는 비슷한 의심을했다. 그래서 기본 코딩을 시도했습니다. 그리고 나는 차이점을 발견했다. 차이점이 있습니다.
string str=null;
Console.WriteLine(str.Length); // Exception(NullRefernceException) for pointing to null reference.
string str = string.Empty;
Console.WriteLine(str.Length); // 0
따라서 "Null"은 절대로 void & "String.Empty"는 일종의 값을 포함하지만 비어 있음을 의미합니다.
""
대 에 관한 것 string.Empty
입니다. 문자열이 비어 있는지 확인하려고 할 때만 null
언급되었습니다.
string.Empty
했는지와readonly
대신에 그것을 선언 한 이유는 무엇입니까const
?