구조체는 본질적으로 필드 집합에 불과합니다. .NET에서는 구조가 객체 인 것처럼 "가장"하는 것이 가능하며, 각 구조 유형에 대해 .NET은 힙 객체가되는 동일한 필드 및 메서드를 사용하여 객체처럼 동작하는 힙 객체 유형을 암시 적으로 정의합니다. . 이러한 힙 객체 ( "박스형"구조)에 대한 참조를 보유하는 변수는 참조 의미론을 표시하지만 구조를 직접 보유하는 변수는 단순히 변수의 집합입니다.
struct-versus-class 혼란의 대부분은 구조가 매우 다른 두 가지 사용 사례를 가지고 있다는 사실에서 비롯된다고 생각합니다. 이것은 매우 다른 디자인 지침을 가져야하지만 MS 지침은 이들을 구분하지 않습니다. 때때로 객체처럼 행동하는 무언가가 필요합니다. 이 경우 MS 지침은 상당히 합리적이지만 "16 바이트 제한"은 아마도 24-32와 비슷할 것입니다. 그러나 때때로 필요한 것은 변수의 집계입니다. 이러한 목적으로 사용되는 구조체는 단순히 여러 개의 공개 필드로 구성되어야하며Equals
오버라이드 .ToString
재정의 및IEquatable(itsType).Equals
이행. 필드의 집계로 사용되는 구조는 개체가 아니므로 가장 하여서는 안됩니다. 구조적 관점에서 필드의 의미는 "이 필드에 마지막으로 기록 된 것"에 불과합니다. 추가 의미는 클라이언트 코드에 의해 결정되어야합니다.
예를 들어, 변수 집계 구조체에 Minimum
및 멤버가 Maximum
있는 경우 구조체 자체는 Minimum <= Maximum
. 이 별도의 통과있는 것처럼 행동한다 파라미터 바와 같은 구조 수신 코드 Minimum
및 Maximum
값. 요구 사항 Minimum
보다 클 수 없습니다 Maximum
것을 요구처럼 간주되어야 Minimum
매개 변수가 별도로 전달보다 클 수 없습니다 Maximum
하나.
때때로 고려해야 할 유용한 패턴은 ExposedHolder<T>
다음과 같은 클래스를 정의하는 것입니다.
class ExposedHolder<T>
{
public T Value;
ExposedHolder() { }
ExposedHolder(T val) { Value = T; }
}
가있는 경우 List<ExposedHolder<someStruct>>
, where someStruct
is a variable-aggregating struct, 하나는 같은 일을 할 수 myList[3].Value.someField += 7;
있지만 myList[3].Value
다른 코드에 제공하면 Value
변경 수단을 제공하지 않고 내용을 제공합니다. 반대로 List<someStruct>
를 사용했다면 var temp=myList[3]; temp.someField += 7; myList[3] = temp;
. 변경 가능한 클래스 유형을 사용하는 경우의 내용 myList[3]
을 외부 코드에 노출하려면 모든 필드를 다른 개체에 복사해야합니다. 변경 불가능한 클래스 유형 또는 "객체 스타일"구조체 myList[3]
를 사용 someField
하는 경우, 다른 점을 제외하고 는 유사한 새 인스턴스를 생성 한 다음 해당 새 인스턴스를 목록에 저장해야합니다.
한 가지 추가 참고 사항 : 유사한 항목을 많이 저장하는 경우 중첩 된 구조 배열에 저장하는 것이 좋을 수 있습니다. 각 배열의 크기를 1K에서 64K 정도 사이로 유지하는 것이 좋습니다. 구조의 배열은 특별합니다. 인덱싱은 구조에 대한 직접 참조를 생성하므로 "a [12] .x = 5;"라고 말할 수 있습니다. 배열과 유사한 개체를 정의 할 수 있지만 C #에서는 이러한 구문을 배열과 공유 할 수 없습니다.