2016-11-27 5 views
2

이없는 동안 당신이 컴파일러 오류왜 증가하는 사업자 심판

에게 발행하는 ref 매개 변수로 속성을 통과하려고하면이

public class Foo 
{ 
    public int Bar { get; set; } = 42; 
} 

같은 클래스가 말 CS0206 속성 또는 인덱서가 외곽 또는 참조로 전달되지 않을 수 있습니다.

이것은 prac 위 예제의 속성은 get_Bar()set_Bar() 메서드로 컴파일됩니다. 그러나 속성에서 증분 연산자를 사용하면

var foo = new Foo(); 
foo.Bar++; 

과 같이 작동합니다.

var foo = new Foo(); 
int tmp = foo.get_Bar(); 
tmp++; 
foo.set_Bar(tmp); 

그래서 이론적으로 컴파일러 같은 ref에 대한 비슷한 일을 할 수있는 :이를 위해, 컴파일러는이 의사 코드 같은 것을 생산하기 위해 필요한 기술적 인 이유가

var foo = new Foo(); 
int tmp = foo.get_Bar(); 
DoSomething(ref tmp); 
foo.set_Bar(tmp); 

을 왜 컴파일러가하지 않거나 C# 팀의 설계 결정 이었습니까?

+2

. 그것은 친숙한 *이 될 수있는 언어의 일종이며, C#은 * 순수한 *을 의미했습니다. 순도가 잠재적으로 값 비쌀 수있는 설정 호출을 숨기거나 잘못된 위치에서 예외를 생성하거나 컴파일하기가 어려우며 컴파일 오류가 발생하거나 앨리어싱 문제가 발생할 수있는 상황에서는 순도가 그다지 좋지 않습니다. 그러나 ++ 연산자는 매우 순수하지 않고 여러 가지 규칙을 적용합니다. 예를 들어, 캐스트없이 * byte *를 증가시킬 수 있습니다. 그들은 실용적으로하기로 결정했습니다. 선택. –

+0

가능한 복제본 : http://stackoverflow.com/questions/1402803/passing-properties-by-reference-in-c-sharp – Abion47

+0

@HansPassant 답변에 사용자의 의견을 자세히 설명 할 수 있다면 받아 들일 것입니다. –

답변

2

HansPassant와 마찬가지로 이것은 C# 팀이 C# 사양을 작성할 때 작성한 디자인 결정이므로 올바른 대답을 얻으려면 그 중 하나를 요청해야합니다.

짐작할 수 있다면, ref과 함께 속성을 전달하는 컴파일러 매직의 양은 해결책을 바람직하지 않게 만드는만큼 충분히 뒤죽박죽 인 작업을 유발할 수 있습니다. 예를 들어, 현재 속성의 증분/감소 방법은 말한대로입니다. 프로그램에서 속성의 배킹 필드 값을 임시 변수에 할당하고 연산을 수행 한 다음 결과를 속성에 다시 할당합니다. 어려운 개념을 포함하지 않는 직접적인 프로세스입니다.

그러나 ref으로 속성을 전달하기 위해 동일한 장면을 마술로 처리하려면 프로세스가 조금 더 복잡해집니다. 값 유형이 ref에 의해 전달되면 매개 변수를 통해 전달되는 실제 값은 값 유형 변수에 대한 포인터입니다. 속성에 대해 이렇게하려면 두 번째 예제와 비슷한 작업을 수행해야합니다. 그 결과, 프로퍼티 자체가 아닌 임시 변수의 주소가 메소드에 전달됩니다. 이런 종류의 행동으로 인해 특정 방식으로 ref 매개 변수를 조작하려는 사람에게 예기치 않게 이해하기 어려운 결과가 발생할 수 있습니다.

증가 연산자는 값만 처리하기 때문에 감싸기가 쉽지만 ref 키워드는 범위와 메모리 주소에 대해 걱정해야하기 때문에 더 복잡합니다.

편집 : 필드에 대해 나에게 발생한 또 다른 이유는 호출 된 메서드 내부의 모든 조작이 필드 자체에 반영됩니다. 이러한 조작은 메소드 실행 중 해당 필드에 액세스 한 다른 스레드 및 기타 스레드에서 볼 수 있습니다 (동시 필드 액세스 기능과 관련한 우수 사례).

그러나 매개 변수의 경우 메서드가 반환되고 값이 다시 복사 될 때까지 메서드 내에서 발생하는 변경 내용은 표시되지 않습니다. 이것은 들판과 특성 사이의 모순 된 행동을 야기 할 수 있는데, 그 원인은 쉽게 알 수 없습니다.

는 (개인적으로, 나는이 없습니다 특성에 ref을 지원하기 위해 더 많은 가능성이 이유라고 생각합니다.)

VB.NET 컴파일러는 코드 컴파일을 만들기 위해 무엇을 사실상