2010-01-07 3 views
14

out 또는 ref 매개 변수에 대한 지정을하면 호출자가 제공 한 참조에 즉시 할당되는 값입니까, 아니면 메서드가 반환 될 때 참조에 할당 된 outref 매개 변수 값입니까? 메서드가 예외를 throw하면 값이 반환됩니까? 예를 들어C# 'out'또는 'ref'매개 변수의 값이 실제로 호출자에게 반환되는 시점은 언제입니까?

: out 파라미터 방법은 발신자가 전달하는 실제 참조하여 작동하도록

int callerOutValue = 1; 
int callerRefValue = 1; 
MyMethod(123456, out callerOutValue, ref callerRefValue); 

bool MyMethod(int inValue, out int outValue, ref int refValue) 
{ 
    outValue = 2; 
    refValue = 2; 

    throw new ArgumentException(); 

    // Is callerOutValue 1 or 2? 
    // Is callerRefValue 1 or 2? 
} 

답변

26

ref 때문에 제어가 리턴되는 경우, 이러한 참조에 대한 모든 변화는 호출자에게 즉시 반영된다.

(당신은 물론 ArgumentException을 잡으려고한다면)이 위의 예에서 의미 outValuerefValue 모두가 outref가에서 동일한 개념을 참고하기 2.

또한 중요하다로 설정됩니다 IL 수준 - out에 대한 추가 규칙을 적용하는 것은 C# 컴파일러에 불과하므로 메서드가 반환하기 전에 값을 설정해야합니다. 따라서 CLR 관점에서 outValuerefValue은 동일한 의미론을 가지며 동일한 방식으로 처리됩니다.

+1

흠 ... 나는 그것이 내가 기대했던 것이 아니지만 시험은 그것을 확증한다! +1. –

+0

이것은 유용한 정보입니다. : O – Sapph

+0

'out'매개 변수를받은 메소드를 마이크로 최적화하는 것을 기억합니다. 이 메소드는 매우 빡빡한 루프에서 호출되었고 매개 변수가 변경되지 않았으므로 호출 될 때마다 필요한 초기화를 제거하기를 원했기 때문에'ref' 매개 변수를 취하게 만들었습니다. 누구든지 이에 대한 설명이 있습니까? 아니면 우연입니까? – JulianR

14

Andrew는 정확합니다. 나는 단지 몇 가지 추가 세부 사항을 추가 할 것입니다.

먼저 out/ref 매개 변수를 생각하는 올바른 방법은 변수에 대한 별칭입니다. 즉, M (ref int q) 메쏘드를 가지고 M (ref x)라고 부를 때, q와 x는과 똑같은 두 개의 다른 이름이 입니다. 변수는 저장 위치입니다. 같은 위치에 두 개의 다른 이름이 있기 때문에 q에 무언가를 저장하면 x에도 저장됩니다.

둘째, 설명하는 대안을 "사본 인/복사 아웃"참조라고합니다. 이 스키마에는 두 개의 저장 위치가 있고 그 중 하나의 내용은 함수 호출 시작시 복사되고 완료되면 다시 복사됩니다. 참고로, copy-in-copy-out의 의미는 예외가 발생할 때 별칭 참조의 의미와 다릅니다.

앨리어싱, X, Q 및 R에서
void M(ref int q, ref int r) 
{ 
    q = 10; 
    r = 20; 
    print (q); 
} 

... 

M(ref x, ref x); 

모두 같은 저장 위치이므로,이 복사 된 복사 아웃 참조 20. 인쇄 :

그들은 같이 기괴한 상황이 다르다 , 이것은 10을 인쇄하고, x의 최종 값은 복사 출력이 왼쪽에서 오른쪽으로 또는 오른쪽에서 왼쪽으로 진행되는지 여부에 따라 달라집니다.

마지막으로 정확하게 기억해 보면, ref 매개 변수에 copy-in-copy-out 의미론을 실제로 구현하는 표현식 트리의 구현에는 희귀하고 기괴한 시나리오가 있습니다. 해당 코드를 검토하고 그 시나리오가 정확히 무엇인지 기억할 수 있는지 확인해야합니다.

관련 문제