문제

.NET에서 차이점은 무엇입니까? String.Empty 그리고 "", 그들은 서로 교환 할 수 있습니까, 아니면 평등에 관한 기본 참조 또는 현지화 문제가 있습니까? String.Empty 문제가되지 않습니까?

도움이 되었습니까?

해결책

버전 2.0 이전 .NET에서 "" 객체를 만듭니다 string.Empty 객체를 생성하지 않습니다심판, 그것은 만든다 string.Empty 더 효율적입니다.

.NET의 버전 2.0 이상에서 "" 동일한 문자열 문자를 참조하십시오 "" 동일합니다 .Empty, 그러나 여전히 빠르지는 않습니다 .Length == 0.

.Length == 0 가장 빠른 옵션이지만 .Empty 약간 더 깨끗한 코드를 만듭니다.

참조 자세한 내용은 .NET 사양입니다.

다른 팁

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
}

스위치 문의 사례 표현

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

이전 답변은 .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의 게시물의 의견에서 이것을 언급합니다.

요약하면, ""vs. string.empty의 실제 결과는 nil입니다. JIT는 결국 그것을 알아낼 것입니다.

나는 개인적으로 JIT가 나보다 훨씬 더 똑똑하다는 것을 알았으므로 마이크로 컴파일러 최적화로 너무 영리하지 않으려 고 노력합니다. JIT는 () 루프를 위해 전개되고, 중복 코드를 제거하고, 인라인 메소드 등을 제거하고, 나 또는 C# 컴파일러가 손에 예상 할 수있는 것보다 더 적절한 시간에 더 나은 시간입니다. JIT가 그 일을하도록하자 :)

String.Empty a 준비 적 현장 "" a Const. 이것은 당신이 사용할 수 없다는 것을 의미합니다 String.Empty 스위치 명령문에서 상수가 아니기 때문에.

또 다른 차이점은 String.Empty가 더 큰 CIL 코드를 생성합니다. ""및 string.empty를 참조하기위한 코드는 길이가 동일하지만 컴파일러는 문자열 연결을 최적화하지 않습니다 (Eric Lippert 's 참조 블로그 게시물) string.empty 인수. 다음 동등한 기능

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 
}

위의 답변은 기술적으로 정확하지만 실제로 사용하고 싶은 것은 최고의 코드 가독성과 예외의 가능성이 가장 낮습니다. string.isnullorempty (s)

나는 사용하는 경향이있다 String.Empty 보다는 "" 간단하지만 명백한 이유는 다음과 같습니다."" 그리고 "" 동일하지 않으며, 첫 번째는 실제로 16 개의 제로 너비 문자를 가지고 있습니다. 분명히 유능한 개발자가 코드에 넣지 않을 것입니다. 그러나 거기에 들어가면 유지 보수 악몽이 될 수 있습니다.

메모:

  • 나는 사용했다 u+feff 이 예에서.

  • 그렇지 않은지 확실하지 않더라도 그 캐릭터를 먹을지 모르겠지만 제로 폭이 많은 캐릭터 중 하나로 직접 시도해보십시오.

  • 나는 이것에 대해서만 감사했다 https://codegolf.stackexchange.com/

사용 String.Empty 보다는 "".

이것은 메모리 사용량보다 속도에 대한 것이지만 유용한 팁입니다. 그만큼 "" 리터럴이므로 문자 그대로 작용합니다. 첫 번째 용도로 생성되고 다음 사용에 대해 참조가 반환됩니다. 하나의 인스턴스 만 "" 우리가 몇 번 사용하더라도 메모리에 저장됩니다! 여기에 메모리 처벌이 보이지 않습니다. 문제는 매번 "" 사용됩니다. 비교 루프가 실행되어 "" 이미 인턴 풀에 있습니다. 반대편에서 String.Emptya에 대한 참조입니다 "" 에 저장 .NET 프레임 워크 메모리 영역. String.Empty vb.net 및 c# 응용 프로그램의 동일한 메모리 주소를 가리키고 있습니다. 그래서 필요한 시간마다 참조를 검색하는 이유 ""그 참조가있을 때 String.Empty?

참조: String.Empty vs ""

String.Empty는 "" ""객체를 생성하지 않습니다. 지적한대로 차이 여기, 그러나 사소한 일입니다.

""의 모든 인스턴스는 동일하고 인턴 된 문자열 리터럴입니다. 따라서 "" "를 사용할 때마다 힙에 새 객체를 던지지는 않지만 동일하고 인턴 된 물체에 대한 참조를 만듭니다. 그렇게 말하면서 나는 string.empty를 선호합니다. 코드를 더 읽기 쉽게 만들어냅니다.

string mystring = "";
ldstr ""

ldstr 메타 데이터에 저장된 문자열 리터럴에 대한 새로운 객체 참조를 푸시합니다.

string mystring = String.Empty;
ldsfld string [mscorlib]System.String::Empty

ldsfld 정적 필드의 값을 평가 스택으로 밀어냅니다.

나는 사용하는 경향이있다 String.Empty 대신에 "" IMHO는 더 명확하고 vb-ish입니다.

엔티티 프레임 워크 관점에서 나오는 것 : EF 버전 6.1.3은 String.Empty와 "" "를 처리 할 때 다르게 처리하는 것으로 보입니다.

string.empty는 유효성 검사 목적으로 널 값으로 취급되며 필요한 (귀속 된) 필드에서 사용되는 경우 검증 오류가 발생합니다. "" "" "유효성 검사를 통과하고 오류를 던지지 않습니다.

이 문제는 EF 7+에서 해결 될 수 있습니다. 참조: - https://github.com/aspnet/entityframework/issues/2610 ).

편집 : [필수 (alluctystrings = true)]는이 문제를 해결하여 string.empty가 검증 할 수 있도록합니다.

string.empty는 컴파일 타임 상수가 아니므로 기능 정의에서 기본값으로 사용할 수 없습니다.

public void test(int i=0,string s="")
    {
      // Function Body
    }

에릭 립퍼트 썼다 (2013 년 6 월 17 일) :
"C# 컴파일러에서 작업 한 첫 번째 알고리즘은 문자열 연결을 처리하는 최적화기였습니다. 불행히도 나는이 최적화를 내가 떠나기 전에 Roslyn 코드베이스에 포트하지 않았다. 바라건대 누군가가 그것에 도착하기를 바랍니다!"

여기에 있습니다 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

코드를 통해 시각적으로 스캔 할 때 "" "색상이 색상화되는 것처럼 보입니다. 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;

여기있는 모든 사람들은 좋은 이론적 설명을했습니다. 나는 비슷한 의심을 가지고 있었다. 그래서 나는 그것에 대한 기본 코딩을 시도했습니다. 그리고 나는 차이를 발견했다. 차이점은 다음과 같습니다.

string str=null;
Console.WriteLine(str.Length);  // Exception(NullRefernceException) for pointing to null reference. 


string str = string.Empty;
Console.WriteLine(str.Length);  // 0

따라서 "null"은 절대적으로 무효가 있음을 의미하는 것 같습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top