UFO ET IT

.NET에서 System.String.Copy를 사용하는 것은 무엇입니까?

ufoet 2020. 11. 24. 20:39
반응형

.NET에서 System.String.Copy를 사용하는 것은 무엇입니까?


매우 어리석은 질문이 아닐까 두렵지 만 뭔가 빠진 게 틀림 없어요.

String.Copy (string) 을 사용하고 싶 습니까?

문서는 방법을 말한다

지정된 String과 동일한 값을 사용하여 String의 새 인스턴스를 만듭니다.

.NET에서는 문자열이 변경 불가능하기 때문에이 방법을 사용하는 것이 어떤 이점이 있는지 잘 모르겠습니다.

 string copy = String.Copy(otherString);

모든 실용적인 목적을 위해 다음과 같은 결과를 산출하는 것처럼 보입니다.

 string copy = otherString;

즉, 진행되는 내부 부기 및 copy가 ReferenceEqualsotherString 이 아니라는 사실을 제외하고 는 식별 가능한 차이점이 없습니다. String은 동일성이 ID가 아닌 값을 기반으로하는 불변 클래스입니다. (내 원래 문구가 Copying과 not 사이에 차이가 있음을 알 수있을만큼 정확하지 않다는 점을 지적 해 준 @Andrew Hare에게 감사 하지만 유용한 차이가 없는 것으로 인식되었습니다 .)

물론 null인수 가 전달 되면 Copy는를 throw ArgumentNullException하고 "새 인스턴스"는 더 많은 메모리를 사용할 수 있습니다. 후자는 거의 혜택처럼 보이지 않으며 null 검사가 전체 Copy 메서드를 보증하기에 충분한 보너스인지 확신하지 못합니다.

감사.


으로 String.Copy당신이 실제로 새로운 메모리를 할당 한 문자열에서 다른 문자를 복사; 두 변수가 동일한 인스턴스가되는 것과는 반대로 완전히 새로운 인스턴스를 얻습니다. 메모리 위치를 직접 처리하고 문자열을 변경할 수있는 비 관리 코드와 함께 문자열을 사용하는 경우 문제가 될 수 있습니다.


String.Copy새를 반환하고 String다음과 같은 결과를 생성하지 않습니다.

String copy = otherString;

이 시도:

using System;

class Program
{
    static void Main()
    {
        String test = "test";
        String test2 = test;
        String test3 = String.Copy(test);

        Console.WriteLine(Object.ReferenceEquals(test, test2));
        Console.WriteLine(Object.ReferenceEquals(test, test3));

        Console.ReadLine();
    }
}

test2 = test이러한 참조 를 설정 하면 동일한 String. Copy함수는 내용은 같지만 힙의 다른 개체 인 String참조를 반환합니다 .


편집 : OP의 질문에 대답하지 않은 꽤 화가 난 많은 사람들이 있습니다. 나는 질문 자체의 잘못된 전제를 수정하여 질문에 답했다고 생각합니다. 다음은 내 요점을 잘 보여줄 유사한 질문과 답변입니다.

질문:

내 차에는 양쪽에 하나씩 두 개의 문이 있습니다. 어떤 문을 사용하든 운전석에 앉게되는 것이 사실이라고 생각합니다. 다른 문의 목적은 무엇입니까?

대답:

사실 어느 쪽 문을 사용하든 운전석에 앉게되는 것은 사실이 아닙니다. 운전석 옆문을 사용하면 운전석이되고 조수석 옆문을 사용하면 조수석이됩니다.

이제이 예에서 "승객 옆문의 목적은 무엇입니까?"라는 질문에 답이 실제로 답이 아니라고 주장 할 수 있습니다. 그러나 그 질문은 전적으로 문이 어떻게 작동하는지에 대한 오해에 근거한 것이기 때문에 전제에 대한 반박이 공제에 의해 다른 문의 목적에 새로운 빛을 비추는 것을 따르지 않습니까?


여기에 퍼즐 조각이 있습니다. 왜 그렇게 하려는지는 설명하지 않지만 기능적 차이를 설명하는 데 도움이됩니다.

fixed키워드를 사용하여 문자열을 고정하면 내용이 변경 될 수 있습니다. 머릿속에서이 일을하고 싶은 상황은 생각할 수 없지만 가능합니다.

string original = "Hello World";
string refCopy = original;
string deepCopy = String.Copy(original);

fixed(char* pStr = original)
{
   *pStr = 'J';
}

Console.WriteLine(original);
Console.WriteLine(refCopy);
Console.WriteLine(deepCopy);

산출:

Jello World
Jello World
Hello World

.NET 4.0 용 BCL을 빠르게 검색하면 string.Copy메서드가 약 6 곳에서 호출 되었음을 알 수 있습니다. 사용법은 대략 다음 범주로 나뉩니다.

  1. 전달 된 문자열을 손상시킬 수있는 네이티브 함수와의 상호 운용을 위해. P / Invoke 선언에 영향을 미칠 수없고 호출되는 함수를 수정할 수없는 string.Copy경우 최선의 선택입니다.

  2. 성능상의 이유로 문자열이 제자리에서 수정되는 상황의 경우. 잠재적으로 긴 문자열에서 몇 개의 문자 만 소문자로 변환해야하는 경우 문자열을 두 번 복사하고 추가 쓰레기를 생성하지 않고이를 수행하는 유일한 방법은이를 변경하는 것입니다.

  3. 필요하지 않은 곳에서. 일부 프로그래머는 Java 또는 C ++ 문자열에 더 익숙하고 C #에서 문자열을 복사하는 것이 거의 유용하지 않다는 사실을 깨닫지 못할 가능성이 높습니다.


string a = "abc";
string b = String.Copy(a);

Monitor.Enter(a); // not the same as Monitor.Enter(b);

하나

string c = "123";
string d = c;
Monitor.Enter(c); // the same as Monitor.Enter(d);

누구든지 신경 쓰는 방법에 관해서는 완전성을 위해 거기에 있다고 생각합니다.


또한

StringBuilder sb = new StringBuilder(100);
sb.Append("abc");
string a = sb.ToString();
string b = String.Copy(a);

내 생각 a다음 더 많은 RAM을 차지합니다 b같은 a크기 (100)의 버퍼에 포인트를 StringBuilder만들었습니다. ( StringBuilder.ToString()방법 내부를보세요 )


.NET 프레임 워크 StringBuilder를 사용 String.Copy()하고 그 일부가되는 것은 .NET Framework StringBuilder의 내용을 변경 한다고 생각 합니다 string. 따라서 a string가 항상 불변 하는 것은 아닙니다.


tvanfosson이 말한 것 외에도 (관리되지 않는 코드에서 관리되는 문자열이 사용하는 버퍼에 액세스 할 수 없다고 생각합니다 ... 적어도 어려울 것임을 알고 있습니다.) 문자열이 다음과 같으면 차이가있을 수 있다고 생각합니다. 다중 스레드 기능에 대한 잠금을 수행하는 개체로 사용됩니다.

예를 들어 ...

using System;

public class Class1
{
    string example1 = "example";
    string example2 = example1;

    public void ExampleMethod1()
    {
        lock (example1)
        {
            Console.WriteLine("Locked example 1");
            //do stuff...
        }
    }

    public void ExampleMethod2()
    {
        lock (example2)
        {
            Console.WriteLine("Locked example 2");
            //do stuff
        }
    }
}

두 예제 메서드가 병렬로 실행되면 동일한 객체를 잠그므로 하나는 잠금 블록 안에있는 동안 다른 하나는 실행할 수 없습니다.

하지만 이렇게 변경하면 ...

using System;

public class Class1
{
    string example1 = "example";
    string example2 = string.Copy(example1);

    public void ExampleMethod1()
    {
        lock (example1)
        {
            Console.WriteLine("Locked example 1");
            //do stuff...
        }
    }

    public void ExampleMethod2()
    {
        lock (example2)
        {
            Console.WriteLine("Locked example 2");
            //do stuff
        }
    }
}

그런 다음 동일한 메서드를 실행하는 다른 스레드의 실행 만 차단할 것이라고 믿습니다 (예 : ExampleMethod1을 실행하는 모든 스레드는 각 작업이 완료 될 때까지 잠기지 만 ExampleMethod2를 실행하는 스레드는 방해하지 않습니다).

Not sure this is a useful difference, since there are better mechanisms for synchronization (I don't think locking strings is a very good idea).


string a = "test";
string b = a;
//Object.ReferenceEquals(a,b) is true
a += "more";
//Object.ReferenceEquals(a,b) is now false !

auto-change detection ?


I am not sure how String being implemented in .NET, but I think Java is a good reference.

In Java, new String(str) also do what String.copy(str); do, allocate a new String with same value.

It seem useless but it is very useful in memory optimization.

String contains a char[] with offset and length in the implementation. If you do a something like a substring, it won't do a memory copy but return a new String instance sharing same char[]. In many cases, this pattern will save a lot of memory copy and allocation. However, if you substring a small piece within a long large String. It will still reference to large char[] even the original large String is able to be GC.

String longString = // read 1MB text from a text file
String memoryLeak = largeString.substring(100,102); 
largeString=null;
// memoryLeak will be sized 1MB in the memory
String smaller = new String(largeString.substring(100,102));
// smaller will be only few bytes in the memory

It can force the new String object allocate it's own char[] to prevent hidden memory leak/waste.

참고URL : https://stackoverflow.com/questions/520895/whats-the-use-of-system-string-copy-in-net

반응형