속성은 변수처럼 보이지만 각 속성은 실제로 get 메서드 및/또는 set 메서드의 조합입니다. 통상, 프로퍼티 get 메소드는, 변수 또는 배열 슬롯에있는 것을 카피합니다. put 메소드는, 그 파라미터를 그 변수 또는 배열 슬롯에 카피합니다. someVariable = someObject.someProeprty;
또는 someobject.someProperty = someVariable;
과 같은 작업을 수행하려는 경우 해당 문구가 각각 var temp=someObject.somePropertyBackingField; someVariable=temp;
및 var temp=someVariable; someObject.somePropertyBackingField=temp;
으로 실행되는 것은 중요하지 않습니다. 반면에 필드를 사용하여 수행 할 수 있지만 속성을 사용하여 수행 할 수없는 작업이 있습니다. 객체가 George
Field1
라는 필드를 노출하면
다음 코드는 다른 방법으로 또는 ref
out
George.Field
파라미터로서 전달할 수있다. 또한 Field1
유형이 노출 된 필드가있는 값 유형 인 경우 해당 필드에 액세스하려는 시도는 George
에 저장된 구조체의 필드에 액세스합니다. Field1
에 속성이나 메서드가 공개되어있는 경우 해당 개체에 액세스하면 ref
매개 변수 인 것처럼 George.Field1
이 해당 메서드로 전달됩니다. George
만약
는 "GET"메서드를 호출하고 임시 변수에 그 결과를 저장합니다 할당 연산자의 왼쪽 아니다 Property1
이라는 속성, Property1
의 다음 액세스를 제공합니다. Property1
필드를 읽으 려하면 임시 변수에서 해당 필드를 읽습니다. Property1
에서 속성 가져 오기 도구 또는 메서드를 호출하면 해당 임시 변수가 해당 메서드에 ref
매개 변수로 전달 된 다음 메서드가 반환 된 후 삭제됩니다. 메서드 또는 속성 getter 또는 메서드 내에서 this
은 임시 변수를 참조하고 메서드가 변경 한 내용은 this
으로 삭제됩니다.
임시 변수의 필드에 쓰는 것은 의미가 없기 때문에 속성 필드에 쓰려고 시도 할 수 없습니다. 또한 현재 버전의 C# 컴파일러는 속성 설정자가 this
을 수정할 가능성이 높으며 따라서 실제로 기본 구조를 수정하지 않더라도 속성 설정자를 사용하지 못하도록합니다. 그 이유는 ArraySegment
은 인덱스 된 get
방법을 포함하고 인덱스 된 set
방법을 포함하지 않기 때문에, 예를 들면, thing.theArraySegment[3] = 4;
컴파일러는 참조가 캡슐화 된 배열을 수정하는 대신 theArraySegment
속성에 의해 반환 된 구조를 수정하려고 시도했다고 생각합니다. 특정 구조 메서드가 this
을 수정할 것이라고 지정하고 구조체 속성에서 호출 할 수 없도록 지정하는 것이 매우 유용 할 수 있지만 아직 그 메커니즘은 없습니다. 하나의 속성에 포함 된 필드에 기록하기를 원한다면
, 최적의 패턴은 일반적으로 : myProperty
의 유형이 관련되지만 독립적 인 값의 고정 세트를 캡슐화하기 위해 설계된 경우
var temp = myThing.myProperty; // Assume `temp` is a coordinate-point structure
temp.X += 5;
myThing.myProperty = temp;
(예 : 점의 좌표), 변수를 필드로 노출하는 것이 가장 좋습니다. 어떤 사람들은 같은 구조가 필요하기 때문에 구조체를 설계하는 것을 선호하는 것 같다 있지만 :
var temp = myThing.myProperty; // Assume `temp` is some kind of XNA Point structure
myThing.myProperty = new CoordinatePoint(temp.X+5, temp.Y);
을 내가 덜 읽을 덜 효율적인, 그리고 더 많은 오류가 발생하기 쉬운 이전의 스타일보다는 같은 코드를 생각한다. 특히 CoordinatePoint
이 발생하면 예 : 매개 변수 X, Y, Z뿐만 아니라 매개 변수 X, Y를 취하고 Z가 0이라고 가정하는 생성자를 노출합니다. 두 번째 형식과 같은 코드는 의도적으로 또는 의도하지 않게 Z를 0으로 만들지 않습니다.반대로 X
이 노출 된 필드 인 경우 첫 번째 양식은 수정 X
일 것입니다.
경우에 따라 클래스가 내부 필드 또는 배열 슬롯을 사용자 정의 루틴에 ref
매개 변수로 전달하는 메소드를 통해 노출하는 것이 도움이 될 수 있습니다. List<T>
-like 클래스는 노출 될이 그
myList.ActOnItem(5, (ref Point pt, ref int ddx) => pt.X += ddx, ref dx);
참고 : 다음 할 수있는 FancyList<CoordinatePoint>
을했고
delegate void ActByRef<T1>(ref T1 p1);
delegate void ActByRef<T1,T2>(ref T1 p1, ref T2 p2);
void ActOnItem(int index, ActByRef<T> proc)
{
proc(ref BackingArray[index]);
}
void ActOnItem<PT>(int index, ActByRef<T,PT> proc, ref PT extraParam)
{
proc(ref BackingArray[index], ref extraParam);
}
코드 IIT에서 항목 5의 X를 필드 일부 지역 변수 dx
을 추가하고 싶었 접근법은 목록에있는 데이터의 적절한 수정을 허용하고 심지어 Interlocked.CompareExchange
과 같은 방법의 사용을 허용합니다. 불행히도 List<T>
에서 파생 된 형식이 이러한 메서드를 지원할 수있는 메커니즘이 없으며 이러한 메서드를 지원하는 형식을 List<T>
이 필요한 코드로 전달할 수있는 메커니즘이 없습니다.
감사합니다. Abel. 귀하의 설명 (값을 반환하는 것은 그것을 복사하는 것과 동일합니다)은 내가 찾고있는 정확한 부분입니다. – NemoStein