IT

.NET에서 전달은 어떻게 전달됩니까?

lottoking 2020. 7. 23. 07:56
반응형

.NET에서 전달은 어떻게 전달됩니까?


a string를 함수에 전달하면 전달의 내용에 대한 포인터가 전달합니다 struct. 아니면 전체 문자열이 스택의 함수에 전달 됩니까?


질문에 대답 다음 코드를 고려하십시오.

void Main()
{
    string strMain = "main";
    DoSomething(strMain);
    Console.Write(strMain); // What gets printed?
}
void DoSomething(string strLocal)
{
    strLocal = "local";
}

여기서 일어날 일을 예측하고 그 이유를 이해하기 위해 알아야 할 세 가지가 있습니다.

  1. K #에서 참조 유형입니다. 그러나 이것은 그림의 일부일뿐입니다.
  2. 라벨은 또한 불변이기 때문에 보일 때마다 언어가 있습니다. 새로운 완전히 이미 만들어지고 참조가 가리키며 이전이 버려집니다.
  3. 전달이 참조 유형이지만 참조로 strMain전달되지 않습니다. 그것은 A의 참조 형, 하지만 기준이되는 값에 의해 전달 . 이것은 까다로운 구별이지만 중요한 것입니다. ref키워드 없이 매개 변수를 세지 않고 매개 변수를 기준으로 out전달했습니다.

그러나 그것은 무엇을 의미합니까?

값으로 참조 유형 전달 : 이미 수행 중

C #에는 두 가지 데이터 유형 그룹 인 참조 유형값 유형이 있습니다 . C #에서 매개 변수를 전달하는 두 가지 방법이 있습니다. 참조 . 이 소리는 동일하며 쉽게 혼동됩니다. 그들은 같은 것이 아닙니다!

ANY 유형의 매개 변수를 전달하고 ref키워드를 사용하지 않는 값으로 전달한 것입니다. 값으로 전달한 경우 전달한 요청 사본입니다. 그러나 그런 매개 변수가 참조 유형 인 경우 복사 한 것은 참조 대상이 아니고 참조 대상 이었습니다 .

다음은 첫 번째 Main방법입니다.

string strMain = "main";

실제로이 줄에서 생성 한 두 가지가 있습니다 : main메모리에 값이 저장된 문자열과 strMain그것을 가리키는 참조 변수 .

DoSomething(strMain);

이제이 참조를 전달합니다 DoSomething. 우리는 그것을 그것을 값으로 전달 했었습니다. 그러나 이것은 참조 참조 유형 자체가 아닌 참조를 복사했음을 의미합니다. 이제 메모리에서 같은 값을 두 개의 참조가 있습니다.

사용자 내부

DoSomething방법 의 상단은 다음과 가능 합니다.

void DoSomething(string strLocal)

ref스케이트와 같이 키워드가 없습니다 . 그래서하지 strLocal않습니다 strMain,하지만 같은 장소에 둘 점. 이렇게 "변경"한다면 strLocal...

strLocal = "local";   

... 저장 값 자체는 변경되지 않습니다 . 우리는 참조를 다시 지적했습니다. 우리는 호출 된 참조를 가져옵니다 strLocal. strMain그렇게하면 어떻게 검증 ? 아무것도. 여전히 오래된 끈을 가리키고 있습니다!

string strMain = "main"; //Store a string, create a reference to it
DoSomething(strMain);    //Reference gets copied, copy gets re-pointed
Console.Write(strMain);  //The original string is still "main" 

불변성은 중요하다

시나리오를 잠시 변경하겠습니다. 우리가 공유로 작업하지 않고 생성 클래스와 같은 변경 가능한 참조 유형을 상상해 처리합니다.

class MutableThing
{
    public int ChangeMe { get; set; }
}

object-에 가리키는 , 대한 참조 따르는 경우 objLocal속성을 변경할 수 있습니다.

void DoSomething(MutableThing objLocal)
{
     objLocal.ChangeMe = 0;
} 

MutableThing메모리는 여전히 하나만 있고 , 복사 된 참조와 원래 참조는 모두가 가리는 것입니다. 자체 의 속성 MutableThing이 변경되었습니다 .

void Main()
{
    var objMain = new MutableThing();
    objMain.ChangeMe = 5; 
    Console.Write(objMain.ChangeMe);  //it's 5 on objMain

    DoSomething(objMain);             //now it's 0 on objLocal
    Console.Write(objMain.ChangeMe);  //it's also 0 on objMain   
}

아,하지만 ...

... 문자열은 변경할 수 없습니다! ChangeMe설정할 속성 이 없습니다 . strLocal[3] = 'H';C 스타일의 char 배열로 할 수 있는 것처럼 할 수 없습니다 . 대신 완전히 새로운 문자열을 구성해야합니다. 변화에 대한 유일한 방법은 strLocal다른 문자열에 대한 참조를 가리 키도록하고, 수단 아무것도 것을 당신은 위해 할 strLocal에 영향을 줄 수 있습니다 strMain. 값은 변경할 수 없으며 참조는 사본입니다.

따라서 문자열이 참조 유형이더라도 값으로 전달하면 호출 수신자에서 진행되는 모든 작업이 호출자의 문자열에 영향을주지 않습니다. 그러나 그것들 참조 유형 이기 때문에 전달하고자 할 때 전체 문자열을 메모리에 복사 할 필요가 없습니다.

추가 리소스 :


C #의 문자열은 변경할 수없는 참조 개체입니다. 이것은 그들에 대한 참조가 (값으로) 전달되고 문자열이 생성되면 수정할 수 없음을 의미합니다. 수정 된 버전의 문자열 (하위 문자열, 잘린 버전 등)을 생성하는 메서드 는 원래 문자열의 수정 된 복사본만듭니다 .


문자열은 특별한 경우입니다. 각 인스턴스는 변경할 수 없습니다. 문자열의 값을 변경하면 메모리에 새 문자열이 할당됩니다.

따라서 참조 만 함수에 전달되지만 문자열이 편집되면 새 인스턴스가되고 이전 인스턴스를 수정하지 않습니다.

참고 URL : https://stackoverflow.com/questions/10792603/how-are-strings-passed-in-net

반응형