โครงสร้างเป็นหัวใจสำคัญไม่มีอะไรมากไปกว่าการรวมเขตข้อมูล ใน. NET เป็นไปได้ที่โครงสร้างจะ "แสร้งทำเป็น" เป็นวัตถุและสำหรับโครงสร้างแต่ละประเภท NET จะกำหนดประเภทวัตถุฮีปโดยปริยายด้วยเขตข้อมูลและวิธีการเดียวกันซึ่งการเป็นวัตถุฮีปจะทำงานเหมือนวัตถุ . ตัวแปรที่มีการอ้างอิงถึง heap object (โครงสร้างแบบ "บรรจุกล่อง") จะแสดงความหมายอ้างอิง แต่ตัวแปรที่มีโครงสร้างโดยตรงเป็นเพียงการรวมตัวแปร
ฉันคิดว่าความสับสนของโครงสร้างเทียบกับคลาสส่วนใหญ่เกิดจากการที่โครงสร้างมีสองกรณีการใช้งานที่แตกต่างกันมากซึ่งควรมีแนวทางการออกแบบที่แตกต่างกันมาก แต่หลักเกณฑ์ของ MS ไม่ได้แยกความแตกต่างระหว่างกัน บางครั้งมีความจำเป็นในบางสิ่งบางอย่างที่มีพฤติกรรมเหมือนสิ่งของ ในกรณีนี้แนวทางของ MS ค่อนข้างสมเหตุสมผลแม้ว่า "ขีด จำกัด 16 ไบต์" น่าจะเป็นแบบ 24-32 มากกว่าก็ตาม อย่างไรก็ตามบางครั้งสิ่งที่จำเป็นคือการรวมตัวแปร โครงสร้างที่ใช้เพื่อจุดประสงค์นั้นควรประกอบด้วยฟิลด์สาธารณะจำนวนมากและอาจเป็นไฟล์Equalsลบล้างการToStringลบล้างและIEquatable(itsType).Equalsการนำไปใช้งาน โครงสร้างที่ใช้เป็นการรวมเขตข้อมูลไม่ใช่วัตถุและไม่ควรแสร้งทำเป็น จากมุมมองของโครงสร้างความหมายของฟิลด์ไม่ควรมีค่ามากกว่าหรือน้อยไปกว่า "สิ่งสุดท้ายที่เขียนถึงฟิลด์นี้" ความหมายเพิ่มเติมใด ๆ ควรถูกกำหนดโดยรหัสไคลเอ็นต์
ตัวอย่างเช่นถ้า struct ตัวแปรรวมมีสมาชิกMinimumและMaximum, struct 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>>ที่ไหนsomeStructก็อาจทำสิ่งต่างๆเช่น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 # ไม่อนุญาตให้แชร์ไวยากรณ์ดังกล่าวกับอาร์เรย์