2023. 10. 4. 15:30

.NET에서 'out'이나 'ref' 한정자를 쓰는데 다음과 같은 에러가 났습니다.

A property or indexer may not be passed as an out or ref parameter

참조를 반환하지 않는 속성 또는 인덱서는 out 또는 ref 값으로 사용할 수 없음

 

 

1. 원인

MS가 제공하는 오류코드만 보고도 확인할 수 있는 오류입니다.

참고 : MS Learn - 컴파일러 오류 CS0206

 

겟터/셋터(getter/setter) 접근자를 이용하여 속성을 만들고 이것을 'out'이나 'ref' 한정자로 전달하려고 하면 발생하는 오류입니다.

 

 

아직도 종종 하는 실수인데.....

.NET은 겟터/셋터(getter/setter) 접근자를 편하게 처리하기 위해 변수명을 그대로 사용할 수 있게 허용해 줍니다.

그러다 보니 이 접근자가 변수인지 착각하는 경우가 있는데.....

사실은 이 접근자를 사용하면 내부에서 함수로 변환하여 관리됩니다.

참고 : MS Learn - 속성 사용(C# 프로그래밍 가이드)

stackoverflow - A property or indexer may not be passed as an out or ref parameter - Mike Chamberlain님 답변

 

 

즉 'out'이나 'ref'한정자는 변수에만 적용할 수 있는데 겟터세터를 넣으면 에러가 나는 게 당연하다는 것입니다.

 

'out'이나나 'ref'한정자는 .NET에서 대표적인 포인터를 다루는 한정자입니다.

할당되지 않은 메모리에 값을 전달할 수 없는 건 당연하다는 것이죠.

 

 

2. 해결 방법

해당 겟터/세터를 접근자를 빼도 되는 속성이면 빼주면 됩니다.

 

 

빼면 안 되는 속성이라면

1) 별도의 변수를 만들고 

2) 속성을 복사한 다음

3) 변수를 전달하고

4) 받은 결과를 다시 속성에 적용합니다.

 

예>

private void Test00()
{
	TestModel temp = new TestModel();

	//에러
	//Test01(ref temp.A, out temp.B);
	
	//백업
	int nTemp_A = temp.A;
	int nTemp_B = temp.B;
	Test01(ref nTemp_A, out nTemp_B);
	//재할당
	temp.A = nTemp_A;
	temp.B = nTemp_B;
}

 

 

마무리

겟터/셋터를 왜 사용하고 어떻게 구현되는지 이해를 못 하고 있다면 겟터/셋터를 빼는 것으로 해결하는 것이 좋습니다.

하지만 겟터/셋터는 무결성을 유지하기 위해 사용하므로 가급적 패턴을 유지하는 것이 좋습니다.