[c#] ref를 사용하는 경우 및 C #에서 필요하지 않은 경우

프로그램의 메모리 상태 인 개체가 있고 상태를 수정하기 위해 개체를 전달하는 다른 작업자 함수도 있습니다. 작업자 함수에 ref로 전달했습니다. 그러나 나는 다음과 같은 기능을 발견했습니다.

byte[] received_s = new byte[2048];
IPEndPoint tmpIpEndPoint = new IPEndPoint(IPAddress.Any, UdpPort_msg);
EndPoint remoteEP = (tmpIpEndPoint);

int sz = soUdp_msg.ReceiveFrom(received_s, ref remoteEP); 

received_s와 둘 다 remoteEP함수에서 물건을 반환 하기 때문에 혼란 스럽습니다 . 이유는 무엇입니까 remoteEP필요성 A가 refreceived_s하지 않는 이유는 무엇입니까?

나는 또한 AC 프로그래머이므로 포인터를 머리에서 꺼내는 데 문제가 있습니다.

편집 : C #의 개체가 내부 개체에 대한 포인터 인 것 같습니다. 따라서 객체를 함수에 전달할 때 포인터를 통해 객체 내용을 수정할 수 있으며 함수에 전달되는 유일한 것은 객체에 대한 포인터이므로 객체 자체가 복사되지 않습니다. 이중 포인터와 같은 함수에서 전환하거나 새 개체를 만들려면 ref 또는 out을 사용합니다.



답변

짧은 대답 : 인수 전달에 대한 기사를 읽으십시오 .

긴 대답 : 참조 유형 매개 변수가 값으로 전달되면 객체의 사본이 아닌 참조 만 전달됩니다 . 이것은 C 또는 C ++에서 포인터 (값으로)를 전달하는 것과 같습니다. 파라미터 자체의 값을 변경하면 호출자 본 이에 레퍼런스 포인트 객체로 변경되지 않습니다 알.

매개 변수 (모든 종류)가 참조 로 전달되면 매개 변수 대한 모든 변경 사항이 호출자 에게 표시됨 을 의미합니다. 매개 변수에 대한 변경 사항 은 변수에 대한 변경 사항입니다.

이 기사는 물론이 모든 것을 더 자세히 설명합니다. 🙂

유용한 답변 : ref / out을 사용할 필요가 거의 없습니다 . 이는 기본적으로 다른 반환 값을 얻는 방법이며, 메서드가 너무 많은 작업을 시도하고 있음을 의미하기 때문에 일반적으로 피해야합니다. 항상 그런 것은 아니지만 ( TryParse등은를 합리적으로 사용하는 표준 예입니다 out) ref / out 사용은 상대적으로 드 물어야합니다.


답변

non-ref 매개 변수를 포인터로, ref 매개 변수를 이중 포인터로 생각하십시오. 이것이 가장 큰 도움이되었습니다.

ref로 값을 전달해서는 안됩니다. Interop 문제가 아니었다면 .Net 팀은 원래 사양에 포함하지 않았을 것입니다. ref 매개 변수가 해결하는 대부분의 문제를 처리하는 OO 방법은 다음과 같습니다.

여러 반환 값의 경우

  • 여러 반환 값을 나타내는 구조체 만들기

메서드 호출의 결과로 메서드에서 변경되는 기본 요소의 경우 (메서드에는 기본 매개 변수에 대한 부작용이 있음)

  • 개체의 메서드를 인스턴스 메서드로 구현하고 메서드 호출의 일부로 개체의 상태 (매개 변수가 아님)를 조작합니다.
  • 다중 반환 값 솔루션을 사용하고 반환 값을 상태에 병합하십시오.
  • 메서드로 조작 할 수있는 상태를 포함하는 개체를 만들고 해당 개체를 기본 요소 자체가 아닌 매개 변수로 전달합니다.

답변

전체 C # 앱을 작성하고 ref로 객체 / 구조체를 전달하지 않을 수 있습니다.

나에게 이렇게 말한 교수가 있었다.

refs를 사용하는 유일한 장소는 다음 중 하나입니다.

  1. 큰 개체 (즉, 개체 / 구조체 내부에 여러 수준의 개체 / 구조체가 있음)를 전달하고 싶은 경우 복사하는 데 비용이 많이 들고
  2. 프레임 워크, Windows API 또는이를 필요로하는 기타 API를 호출하고 있습니다.

할 수 있다고해서하지 마십시오. 매개 변수의 값을 변경하기 시작하고주의를 기울이지 않으면 몇 가지 불쾌한 버그로 인해 엉덩이에 약간 걸릴 수 있습니다.

나는 그의 조언에 동의하며, 학교 이후 5 년이 지난 지금까지 프레임 워크 나 Windows API를 호출하는 것 외에는 필요가 없었습니다.


답변

received_s는 배열이므로 해당 배열에 대한 포인터를 전달합니다. 이 함수는 기본 위치 나 포인터를 변경하지 않고 기존 데이터를 제자리에서 조작합니다. ref 키워드는 실제 포인터를 위치에 전달하고 해당 포인터를 외부 함수에서 업데이트하므로 외부 함수의 값이 변경됨을 나타냅니다.

예를 들어, 바이트 배열은 이전과 이후의 동일한 메모리에 대한 포인터이며 메모리가 방금 업데이트되었습니다.

Endpoint 참조는 실제로 외부 함수의 Endpoint에 대한 포인터를 함수 내부에서 생성 된 새 인스턴스로 업데이트합니다.


답변

참조를 참조로 포인터를 전달한다는 의미로 참조를 생각하십시오. ref를 사용하지 않으면 값으로 포인터를 전달한다는 의미입니다.

더 나은 방법은 방금 말한 내용을 무시하고 (특히 값 유형에서 오해의 소지가있을 수 있음) This MSDN page를 읽는 것 입니다.


답변

내 이해는 Object 클래스에서 파생 된 모든 객체는 포인터로 전달되는 반면 일반 유형 (int, struct)은 포인터로 전달되지 않고 ref가 필요하다는 것입니다. 나는 문자열에 대해 확신하지 못합니다 (최종적으로 Object 클래스에서 파생됩니까?)


답변

Jon Skeet의 전체 답변과 다른 답변에 동의하지만를 사용하는 사용 사례가 ref있으며 이는 성능 최적화를 강화하는 것입니다. 성능 프로파일 링 중에 메서드의 반환 값을 설정하면 성능에 약간의 영향을주는 반면 ref반환 값이 해당 매개 변수에 채워지는 인수로 사용 하면이 약간의 병목 현상이 제거되는 것으로 나타났습니다.

이것은 최적화 노력이 극도의 수준으로 진행되어 가독성과 테스트 가능성 및 유지 관리 가능성을 희생하여 밀리 초 또는 스플릿 밀리 초를 절약하는 경우에만 유용합니다.