아무 생각 없이 Class의 Property를 함수의 ref 타입 파라미터로 넘기려다가 아래 에러를 만났다.
error[kr] : 속성 또는 인덱서는 out 또는 ref 매개 변수로 전달할 수 없습니다.
error[en] : A property or indexer may not be passed as an out or ref parameter.
Q1. 왜 넘길 수 없는가?
왜 넘길 수 없는지 이해하려면 먼저 Property가 기본적으로 어떻게 동작하는지 알아야 한다.
아래와 같은 Property를 가정해보자
public int TestProperty { get; set; }
컴파일러는 컴파일타임에 아래와 비슷한 모양으로 testProperty라는 필드 생성 및 Get, Set 메서드를 생성한다.
이후 TestProperty라는 속성을 읽거나 쓸때 이 메서드들을 호출하는 방식으로 동작한다.
private int testProperty;
public int TestProperty
{
get { return testProperty; }
set { testProperty = value; }
}
다시 ref 키워드로 넘어오면 ref 키워드는 넘어온 파라메터에 대해
변수에 대한 참조(reference to a variable)를 기대하고 있다.
즉, 내부적으로 동작할때 변수의 주소를 사용한다.
둘을 종합해보면 ref 키워드 파라메터로 Property를 넘길경우 testProperty 필드의 주소 값을 이용해 동작해 문제가 없을 것 같아 보인다.
하지만 아래와 같은 케이스를 생각해보자.
setter 없이 int.MinValue만 리턴하는 Property의 경우
컴파일러 입장에서 값을 변경할 때 어떤 변수에 대한 참조를 사용할지 알 방법이 없다.
public int TestProperty
{
get { return int.MinValue; }
}
위 케이스는 많은 예시중 하나일 뿐 Property의 특성상 getter, setter 내부 구현이 자유로우므로 컴파일러 입장에서
"속성 또는 인덱서는 out 또는 ref 매개 변수로 전달할 수 없습니다." 에러를 뱉는 건 생각해보면 당연한 일이다.
Q2. Field는 ref (혹은 out) 매개 변수로 전달이 가능한가?
가능하다.
Q3. 그렇다면 Field와 Property의 차이점은 무엇인가?
몰랐던 차이점 중 알아두면 좋을 것 같은 것을 정리해보면 아래와 같다.
- 인터페이스에서의 사용 가능 여부 (Property만 사용 가능하다.)
- Public Field는 FxCop 위반이다.
ref : https://stackoverflow.com/questions/4142867/what-is-the-difference-between-a-property-and-a-variable