.NET에서 전달은 어떻게 전달됩니까?
a string
를 함수에 전달하면 전달의 내용에 대한 포인터가 전달합니다 struct
. 아니면 전체 문자열이 스택의 함수에 전달 됩니까?
질문에 대답 다음 코드를 고려하십시오.
void Main()
{
string strMain = "main";
DoSomething(strMain);
Console.Write(strMain); // What gets printed?
}
void DoSomething(string strLocal)
{
strLocal = "local";
}
여기서 일어날 일을 예측하고 그 이유를 이해하기 위해 알아야 할 세 가지가 있습니다.
- K #에서 참조 유형입니다. 그러나 이것은 그림의 일부일뿐입니다.
- 라벨은 또한 불변이기 때문에 보일 때마다 언어가 있습니다. 새로운 완전히 이미 만들어지고 참조가 가리키며 이전이 버려집니다.
- 전달이 참조 유형이지만 참조로
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 #에서 참조 유형과 값 유형의 차이점 과 참조 유형이 참조 전달 매개 변수와 동일하지 않은 이유 에 대해 읽은 최고의 기사 입니다.
- 평소와 같이 Eric Lippert는 주제에 대한 여러 훌륭한 블로그 게시물을 보유하고 있습니다.
- 그는 불변성 에 대해서도 훌륭한 것들을 가지고 있습니다.
C #의 문자열은 변경할 수없는 참조 개체입니다. 이것은 그들에 대한 참조가 (값으로) 전달되고 문자열이 생성되면 수정할 수 없음을 의미합니다. 수정 된 버전의 문자열 (하위 문자열, 잘린 버전 등)을 생성하는 메서드 는 원래 문자열의 수정 된 복사본 을 만듭니다 .
문자열은 특별한 경우입니다. 각 인스턴스는 변경할 수 없습니다. 문자열의 값을 변경하면 메모리에 새 문자열이 할당됩니다.
따라서 참조 만 함수에 전달되지만 문자열이 편집되면 새 인스턴스가되고 이전 인스턴스를 수정하지 않습니다.
참고 URL : https://stackoverflow.com/questions/10792603/how-are-strings-passed-in-net
'IT' 카테고리의 다른 글
새로운 Firebase 클라우드 메시징 시스템이 포함 된 알림 아이콘 (0) | 2020.07.23 |
---|---|
한 달에 일수에서 (0) | 2020.07.23 |
각도 ng- 변화 지연 (0) | 2020.07.23 |
"svn update"명령을 실행하기 전에 리포지토리에서 업데이트 확인하는 방법은 무엇입니까? (0) | 2020.07.23 |
emacs 자바 확장 모드에서 들여 쓰기 너비를 변경하는 방법 (0) | 2020.07.23 |