문제

문자열을 참조 형식도 특성의 대부분은 값의 형식과 같이 되는 불변 및 데==오버로드를 비교하는 텍스트를 만들기 보다는 오히려 그들을 참조는 동일한 개체입니다.

지 않는 이유는 무엇 문자열 값을 입력한 후?

도움이 되었습니까?

해결책

문자열은 거대 할 수 있기 때문에 가치 유형이 아니며 힙에 저장해야합니다. 값 유형은 (아직 CLR의 모든 구현에서) 스택에 저장된 것입니다. 스택 스택 할당 줄은 모든 종류의 물건을 깨뜨릴 것입니다. 스택은 32 비트의 경우 1MB, 64 비트의 경우 4MB에 불과합니다. 각 문자열을 상자에 넣어야합니다. 사본 페널티를 사용하고, 인턴 문자열 및 메모리 사용량을 할 수 없습니다. 풍선 등 ...

(편집 : 값 유형 스토리지에 대한 설명이 구현 세부 사항으로 추가되어 System.ValueType. 감사합니다. 감사합니다.)

다른 팁

성능 (공간과 시간!)이 값 유형이면 끔찍한 유형이 아닙니다. 값 유형이면 값이 끔찍하고 방법이 전달되고 방법 등으로 반환 될 때마다 값을 복사해야했기 때문입니다.

세상을 제정신으로 유지하는 것은 가치 의미를 가지고 있습니다. 코딩하는 것이 얼마나 어려운지 상상할 수 있습니까?

string s = "hello";
string t = "hello";
bool b = (s == t);

세트 b 되려고 false? 응용 프로그램에 대해 얼마나 어려운지 코딩이 얼마나 어려운지 상상해보십시오.

참조 유형과 가치 유형의 구별은 기본적으로 언어 설계에서 성능 트레이드 오프입니다. 참조 유형은 건설 및 파괴 및 쓰레기 수집에 대한 오버 헤드가 있습니다. 반면에 값 유형은 전체 객체가 포인터가 아닌 복사되기 때문에 메소드 호출 (데이터 크기가 포인터보다 큰 경우)에 대한 오버 헤드가 있습니다. 문자열은 포인터의 크기보다 훨씬 크기 (일반적으로) 될 수 있기 때문에 참조 유형으로 설계되었습니다. 또한 Servy가 지적했듯이 값 유형의 크기는 컴파일 시간에 알려져야하며, 이는 항상 문자열의 경우는 아닙니다.

돌연변이 성 문제는 별도의 문제입니다. 기준 유형과 값 유형은 모두 변이 가능하거나 불변 할 수 있습니다. 변이 가능한 값 유형에 대한 의미론은 혼란 스러울 수 있기 때문에 값 유형은 일반적으로 불변입니다.

기준 유형은 일반적으로 변이 가능하지만 의미가있는 경우 불변으로 설계 할 수 있습니다. 문자열은 특정 최적화를 가능하게하기 때문에 불변으로 정의됩니다. 예를 들어, 동일한 문자열 문자가 동일한 프로그램에서 여러 번 발생하면 (매우 일반적) 컴파일러는 동일한 객체를 재사용 할 수 있습니다.

그렇다면 왜 "=="가 텍스트로 문자열을 비교하기 위해 과부하됩니까? 가장 유용한 의미이기 때문입니다. 두 문자열이 텍스트별로 동일하면 최적화로 인해 동일한 객체 참조가 될 수도 있고 아닐 수도 있습니다. 따라서 참조를 비교하는 것은 쓸모가 없지만 텍스트를 비교하는 것은 거의 항상 원하는 것입니다.

더 일반적으로 말하면, 문자열에는 불리는 것이 있습니다 가치 의미론. 이것은 C# 특정 구현 세부 사항 인 값 유형보다 더 일반적인 개념입니다. 가치 유형은 가치 의미를 가지고 있지만 참조 유형은 또한 가치 의미를 가질 수 있습니다. 유형에 가치 의미가있는 경우 기본 구현이 참조 유형 또는 값 유형인지 실제로 알 수 없으므로 구현 세부 사항을 고려할 수 있습니다.

이것은 오래된 질문에 대한 늦은 답변이지만, 다른 모든 답변은 요점을 놓치고 있습니다. 즉 .NET은 2005 년 .NET 2.0까지 제네릭이 없었습니다.

String 값 유형 대신 참조 유형입니다. Microsoft가 현자가 아닌 컬렉션에서 가장 효율적인 방식으로 문자열을 저장할 수 있도록 Microsoft가 매우 중요했습니다., 와 같은 System.Collection.ArrayList.

값 유형을 비 게니어 컬렉션에 저장하려면 유형으로의 특별한 변환이 필요합니다. object 권투라고합니다. CLR이 값 유형을 상자에 올리면 값을 System.Object 그리고 그것을 관리하는 힙에 저장합니다.

컬렉션에서 값을 읽으려면 Unboxing이라고하는 역 작동이 필요합니다.

권투 및 Unboxing은 모두 무시할 수없는 비용이 있습니다. 권투는 추가 할당이 필요하며, Unboxing에는 유형 확인이 필요합니다.

일부 답변은 잘못 주장합니다 string 크기가 가변적이기 때문에 값 유형으로 구현할 수 없었습니다. 실제로 작은 문자열 최적화 전략을 사용하여 고정 길이의 데이터 구조로 문자열을 구현하는 것은 쉽습니다. 문자열은 외부 버퍼에 대한 포인터로 저장되는 큰 문자열을 제외하고는 유니 코드 문자 시퀀스로 직접 메모리에 저장됩니다. 두 표현 모두 동일한 고정 길이, 즉 포인터 크기를 갖도록 설계 될 수 있습니다.

제네릭이 첫날부터 존재한다면 값 유형으로 문자열을 갖는 것이 더 나은 솔루션이었을 것입니다. ㅏ List<string> 작은 문자열 만 포함하는 것은 단일 연속 메모리 블록 일 수 있습니다.

문자열뿐만 아니라 불변의 참조 유형이 아닙니다.멀티 캐스트 대표도.그렇기 때문에 글을 쓰는 것이 안전합니다

protected void OnMyEventHandler()
{
     delegate handler = this.MyEventHandler;
     if (null != handler)
     {
        handler(this, new EventArgs());
     }
}

나는 현이 불변이라고 생각합니다. 왜냐하면 이것은 그들과 함께 일하고 기억을 할당하는 가장 안전한 방법이기 때문입니다. 왜 가치 유형이 아닌가? 이전 저자는 스택 크기 등에 대해 옳습니다. 또한 프로그램에서 동일한 상수 문자열을 사용할 때 문자열을 참조 유형으로 만들 수 있습니다. 당신이 정의하는 경우

string s1 = "my string";
//some code here
string s2 = "my string";

"내 문자열"상수의 두 인스턴스는 어셈블리에 한 번만 할당 될 가능성이 있습니다.

일반적인 참조 유형과 같은 문자열을 관리하려면 문자열을 새 StringBuilder (문자열 S) 안에 넣으십시오. 또는 MemoryStreams를 사용하십시오.

당신이 당신의 함수에서 거대한 문자열을 전달할 것으로 기대하는 라이브러리를 만들려면, 매개 변수를 StringBuilder 또는 스트림으로 정의하십시오.

또한 스트링이 구현되는 방식 (각 플랫폼마다 다르기)과 함께 스티치를 시작할 때. 사용하는 것처럼 StringBuilder. 그것은 당신이 끝에 도달하면 복사 할 수있는 버퍼를 할당합니다. 일단 당신이 끝나면, 당신이 큰 일치 성능을 수행하면 방해받지 않기를 희망하면서 당신을 위해 더 많은 기억을 할당합니다.

아마도 Jon Skeet가 여기서 도울 수 있습니까?

주로 성능 문제입니다.

문자열이 값 유형처럼 행동하면 코드를 작성할 때 도움이되지만 값 유형이되면 큰 성능을 얻을 수 있습니다.

심도있는 모습을 위해 좋은 기사 .NET 프레임 워크의 문자열에서.

어떻게 말할 수 있습니까? string 참조 유형입니까? 그것이 어떻게 구현되는지 확실하지 않습니다. C#의 문자열은 정확하게 불변 으로이 문제에 대해 걱정할 필요가 없습니다.

실제로 문자열은 가치 유형과의 유사성이 거의 없습니다. 우선, 모든 값 유형이 불변이 아닌 것은 아니며, 원하는 모든 것을 원하는 int32의 값을 변경할 수 있으며 여전히 스택에서 동일한 주소가 될 수 있습니다.

문자열은 아주 좋은 이유 때문에 불변이 아니며, 참조 유형과 관련이 없지만 메모리 관리와 관련이 없습니다. 문자열 크기가 변경 될 때 관리 된 힙의 주위를 바꾸는 것보다 새로운 객체를 만드는 것이 더 효율적입니다. 가치/참조 유형과 불변의 개체 개념을 함께 혼합하고 있다고 생각합니다.

"=="까지 : "=="은 연산자 과부하이며, 문자열로 작업 할 때 프레임 워크를 더 유용하게 만드는 매우 좋은 이유 때문에 다시 구현되었습니다.

매우 간단한 단어로 명확한 크기를 가진 값은 값 유형으로 취급 될 수 있습니다.

문자열이 문자 배열로 구성되는 것만 큼 단순하지 않습니다. 나는 문자열을 문자 배열로 본다 []. 따라서 참조 메모리 위치가 스택에 저장되고 힙의 배열 메모리 위치의 시작 부분을 가리키기 때문에 힙에 있습니다. 문자열 크기는 할당되기 전에 알려지지 않았습니다 ... 힙에 적합합니다.

그렇기 때문에 문자열이 크기가 같은 경우에도 변경할 때 컴파일러는이를 알지 못하고 새로운 배열을 할당하고 배열의 위치에 문자를 할당해야하기 때문에 문자열이 실제로 불변입니다. 문자열을 언어가 즉시 메모리를 즉석에 할당하지 않도록 보호하는 방식으로 문자열을 생각한다면 (프로그래밍과 같은 C 읽기)

에서의 위험을 얻는 또 다른 아래 신비한-투표는다는 사실을 많이 언급한 스택과 메모리와 관련하여 가치 종류와 기본 형식이기 때문에 그들은 해야 합 맞으로 등록에서 마이크로프로세서로 가능합니다.할 수 없습 밀어 또는 팝업에게 뭔가/스택에서 걸리는 경우보다 더 많은 비트 레지스터가있다....이 지침은,예를 들어"pop eax"--기 때문에 eax 은 32 비트에서 32 비트 시스템입니다.

부동 소수점 기본 형식에 의해 처리됩 FPU 는 80bits 넓습니다.

이 모든기로 결정했 오래 전에 있었 OOP 언어를 당황하게 정의하는 기본 형식 그리고 내가 생각하는 값을 입력하는 용어입을 위해 특별히 만들어졌 OOP 언어입니다.

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