การเขียนโปรแกรมแบบวัตถุวิธีในภาษาซีชาร์ป (OOP with C#) ตอนที่ 3

การเขียนโปรแกรมแบบวัตถุวิธีในภาษาซีชาร์ป (OOP with C#) ตอนที่ 3
พรอพเพอร์ตี ของดีใน C#
ในตอนที่ผ่านมาผู้เขียนได้พูดถึงพรอพเพอร์ตี (property) ไปแล้วอย่างคร่าวๆในบทความตอนนี้ได้เวลาที่จะพูดถึงพรอพเพอร์ตีโดยละเอียดเสียที
พรอพเพอร์ตีเป็นเรื่องสำคัญ มันเป็นสมาชิกของคลาสที่ช่วยให้เราเขียนโปรแกรมตามลัทธิวัตถุวิธีได้ง่ายขึ้นและสวยงามขึ้น
มันเป็นคุณสมบัติพิเศษในภาษาซีชาร์พที่ท่านจะไม่พบในภาษาอื่น
การศึกษาให้เข้าใจว่าพรอพเพอร์คืออะไร มีประโยชน์อย่างไร
และใช้งานอย่างไรจะช่วยให้ท่านเขียนโค้ดแบบ OOP ในภาษาซีชาร์พได้อย่างสง่างาม
การที่จะเข้าใจพรอพเพอร์ตี ท่านจำเป็นต้องเข้าใจสี่หัวข้อต่อไปนี้
- สมาชิกแบบฟิลด์
- เอนเคปซูเลชัน
- การเชื่อมหลวม
- เกตเตอร์ / เซตเตอร์
สมาชิกแบบฟิลด์
ต่อไปนี้จะพูดถึงฟิลด์เฉพาะส่วนที่เกี่ยวข้องกับพรอพเพอร์ตี- ฟิลด์คือตัวแปรทำหน้าที่เก็บข้อมูลของออพเจ็กต์
- ตัวแปรที่เป็นสมาชิกแบบฟิลด์ คือตัวแปรที่เราประกาศไว้นอกเมธอดในคลาส
- และเราได้กำหนด “แอกเซสโมดิไฟเออร์” (Access modifier ตัวกำหนดระดับสิทธิการเข้าถึง) ของมันไว้ให้เป็นแบบไพรเวท (private) เพราะเราต้องการใช้ตัวแปรนี้เพื่อกิจการภายในคลาสนี้เท่านั้น โค้ดภายนอกไม่ควรรู้ถึงการมีอยู่ของมันเลย
โค้ดที่ท่านเห็นในภาพที่ 1 แสดงความแตกต่างระหว่างฟิลด์แบบไพรเวทและแบบฟิลด์แบบที่ไม่ใช่ไพรเวท
และยังแสดงให้เห็นความแตกต่างระหว่างตัวแปรแบบฟิลด์กับตัวแปรธรรมดาด้วย
ก่อนจะอ่านคำอธิบายโค้ดขอให้ท่านทำความเข้าใจคำว่า “โค้ดภายใน” และ “โค้ดภายนอก” เสียก่อน
เพราะนี่เป็นแนวคิดแบบวัตถุวิธี ถ้าท่านไม่เข้าใจสองคำนี้ ท่านก็จะไม่เข้าในแนวคิดที่แฝงอยู่ในโค้ดตัวอย่างนี้
ฉากเหตุการณ์ปรกติที่เกิดขึ้นในการพัฒนาแอพลิเกชันซอฟต์แวร์ คือ ท่านนิยามคลาสไว้ (ในตัวอย่างนี้คือคลาส Student) เป็นคลาสที่จะถูกนำไปใช้โดยท่านเอง
หรือโดยนักเขียนโค้ดผู้อื่นในโครงการปัจจุบัน หรือในอนาคตก็ได้ (ตามหลักการนำโค้ดกลับมาใช้ใหม่ (code reusable)
ซึ่งเป็นประโยชน์หลักอย่างหนึ่งในลัทธิวัตถุวิธี) โค้ดทั้งหมดภายในคลาส Student ผู้เขียนจะเรียกว่า “โค้ดภายใน” (ภาษาอังกฤษเรียกว่า internal code หรือ host code)
ส่วนโค้ดที่ (ท่านเองหรือนักเขียนโค้ดผู้อื่นในโครงการปัจจุบันหรืออนาคตเขียน)
เขียนขึ้นเพื่อนำคลาส Student ไปใช้สร้างออพเจ็กต์ (ในตัวอย่างนี้คือคลาส School)
ผู้เขียนจะเรียกว่า “โค้ดภายนอก” (external code หรือ client code)
กล่าวโดยสรุปคือให้ท่านเพ่งเล็งคลาสที่เรากำลังนิยามอยู่เป็นหลัก และให้จินตนาการว่าต่อไปในอนาคตจะมีโค้ดภายนอกมาเรียกหาคลาสนี้เพื่อสร้างออพเจ็กต์
ในตัวอย่างนี้เราจะยึดเอาคลาส Student เป็นศูนย์กลาง โค้ดอื่น ๆ นอกเหนือจากนี้เราจะว่าถือเป็นโค้ดภายนอกทั้งนั้น
โค้ดบรรทัดที่ 3 ถึง 13 คือนิยามคลาส Student ซึ่งเป็นคลาสหลักของตัวอย่างนี้
ส่วนโค้ดบรรทัดที่ 17 ถึง 21 เป็นนิยามคลาส school ซึ่งมีโค้ดที่จะนำคลาส Student ไปสร้างออพเจ็กต์ คลาส Student จึงเป็นโค้ดภายนอก
โค้ดบรรทัดที่ 5 ประกาศตัวแปรชื่อ age เนื่องจากตัวแปรนี้ถูกประกาศไว้นอกเมธอดใด ๆ จึงทำให้มันมีฐานะเป็น “สมาชิกประเภทฟิลด์” (Field member)
โปรดสังเกตว่าผู้เขียนได้กำหนดแอกเซสโมดิไฟเออร์ของมันไว้ให้เป็นแบบไพรเวท (private) ทำให้โค้ดภายนอกไม่สามารถเข้าถึง (อ่านหรือเขียน) ตัวแปรตัวนี้ได้
โค้ดบรรทัดที่ 6 ประกาศตัวแปรชื่อ grade เนื่องจากตัวแปรนี้ถูกประกาศไว้นอกเมธอดใด ๆ จึงทำให้มันมีฐานะเป็นฟิลด์ เช่นเดียวกับ age
โปรดสังเกตว่าผู้เขียนไม่ได้กำหนดแอกเซสโมดิไฟเออร์ของมันไว้ คอมไพเลอร์ (compiler ตัวแปรภาษา)
จะถือว่าตัวแปรนี้เป็นแบบไพรเวทโดยปริยาย มีผลให้โค้ดภายนอกไม่สามารถเข้าถึงตัวแปรตัวนี้ได้เช่นกัน
โค้ดบรรทัดที่ 7 ผู้เขียนประกาศตัวแปรชื่อ name เนื่องจากตัวแปรนี้ถูกประกาศไว้นอกเมธอดใด ๆ จึงทำให้มันมีฐานะเป็นฟิลด์ เช่นเดียวกับ age และ grade
โปรดสังเกตว่าผู้เขียนกำหนดแอกเซสโมดิไฟเออร์ของมันไว้ให้เป็นพับลิก จึงมีผลให้โค้ดภายนอกสามารถเข้าถึงตัวแปรตัวนี้ได้ด้วย
นี่คือตัวอย่างการเขียนโค้ดที่ผิดดังจะอธิบายต่อไป
โค้ดบรรทัดที่ 10 ประกาศตัวแปรชื่อ subject เป็นการประกาศโดยไม่ระบุแอกเซสโมดิไฟเออร์
คอมไพเลอร์จึงถือว่าตัวแปรนี้มีแอกเซสโมดิไฟเออร์เป็นแบบไพรเวทไปโดยปริยาย
และเนื่องจากตัวแปรตัวนี้ถูกประกาศไว้ภายในเมธอด (เมธอด Entroll)
จึงมีผลให้มันมีภาวะเป็นตัวแปรธรรมดา ไม่ใช่ “สมาชิกประเภทฟิลด์” (Field member) เหมือนอย่างตัวแปร age, grade และ name
แล้วตัวแปรธรรมดาต่างจากตัวแปรที่เป็นสมาชิกประเภทฟิลด์อย่างไร คำตอบคือต่างกันที่สโคป (scope) หรือขอบเขตอายุ
ตัวแปรธรรมดาจะมีชีวิตอยู่ภายในเมธอดเท่านั้น
เมื่อเมธอดสิ้นสุดการทำงานลงตัวแปรจะตายไป ขณะที่ฟิลด์มีอายุยืนกว่า คืออายุขัยของมันจะเท่ากับออพเจ็กต์
ฟิลด์จะมีชีวิตอยู่ตราบเท่าที่ออพเจ็กต์ยังมีชีวิตอยู่ และถูกทำลายไปพร้อมกับออพเจ็กต์เมื่อออพเจ็กต์จบชีวิต
ออพเจ็กต์จะตายเมื่อไม่มีโค้ดใด ๆ อ้างถึงมัน และจะถูกนำไปกำจัดโดย “การ์เบจคอลเลคเตอร์” (garbage collector) ต่อไป
ต่อไปนี้จะพูดถึงเอสแคปซูเลชันเฉพาะส่วนที่เกี่ยวข้องกับพรอพเพอร์ตี
ในการออกแบบและเขียนโปรแกรมตามลัทธิวัตถุวิธี (Object Oriented Design/Programming)
มีแนวคิด เอนแคปซูเลชัน (Encapsulation) ที่ไม่ต้องการให้โค้ดภายนอกเข้าถึง ตัวแปรที่เป็นสมาชิกแบบฟิลด์ (field member) ของคลาสอื่นได้โดยตรง
หรือพูดอีกอย่างหนึ่งคือห้ามโค้ดภายนอกยุ่งกับกิจการภายในของคลาสอื่น พูดแบบภาษาหนังสือพิมพ์คือห้าม “ล้วงลูก” นั่นเอง
โค้ดบรรทัดที่ 14 ถึง 21 คือนิยามคลาส school นี่คือคลาสที่จะนำ Student ไปใช้งาน
มันจึงเป็นโค้ดภายนอกเพราะตอนนี้เรากำลังออกแบบสร้างคลาส Student อยู่
เราจึงยึดเอา Student เป็นศูนย์กลางของภาพ ดังนั้นโค้ดบรรทัดที่ 4 ถึง 13 จึงเป็นโค้ดภายใน ส่วนโค้ดอื่น ๆ ถือว่าเป็นโค้ดภายนอกทั้งสิ้น
โค้ดบรรทัดที่ 18 สร้างออพเจ็กต์ (ที่ถูกชี้โดยตัวแปร) ชื่อ myStudent จากคลาส Student
โค้ดบรรทัดที่ 19 เราเปลี่ยนแปลงค่าของตัวแปร name ซึ่งตัวแปรนี้เป็นสมาชิกแบบฟิลด์ (field member) ของออพเจ็กต์
นี่คือการ “ล้วงลูก” เพราะโค้ดในคลาส Student ซึ่งเป็นโค้ดภายนอกเข้าถึง ตัวแปร name ที่เป็นสมาชิกแบบฟิลด์ (field member) ของคลาส Student โดยตรง
นี่คือการกระทำที่ผิดหลักเอนเคปซูเลชัน
ในภาษาซีพลัสพลัสและจาวาจะใช้วิธีทำ เกตเตอร์ / เซตเตอร์ ส่วนภาษาซีชาร์พก้าวหน้าไปอีกระดับหนึ่ง
เพราะมีกลไกที่เรียกว่า “พรอพเพอร์ตี” ที่มีไว้เพื่อการนี้โดยเฉพาะ
การออกแบบซอฟต์แวร์ในลัทธิวัตถุวิธี
การเชื่อมหลวม (loose coupling) คือดี
การเชื่อมแน่น (tight coupling) ไม่ดี
การเชื่อมแน่นคือ คลาสสองคลาส (หรือมากกว่า) ขึ้นอยู่แก่กัน เมื่อเราแก้โค้ดในคลาสหนึ่ง จะส่งผลกระทบไปยังอีกคลาสหนึ่ง
ส่วนการเชื่อมหลวมคือเราออกแบบให้ทุกคลาสมีอิสระต่อกัน เมื่อเราเปลี่ยนแปลงโค้ดในคลาสหนึ่ง จะไม่ส่งผลกระทบไปที่ไหนทั้งนั้น
การจะทำให้เกิดการเชื่อมหลวม เราต้องออกแบบให้คลาสหนึ่งคลาสทำหน้าที่เพียงเรื่องเดียว (high cohesion)
และแยกประเด็นไม่ให้พัวกันกัน (separation of concerns) รายละเอียดเรื่องนี้ค่อนข้างยาว ผู้เขียนจะนำเสนอในบทความตอนต่อ ๆ ไป
การให้โค้ดภายนอกอ่านหรือเขียนค่าภายในของออพเจ็กต์ผ่านเมธอดทั้งสองนี้ ช่วยส่งเสริมแนวคิดเอนเคปซูเลชัน
เพราะผู้เขียนโค้ดภายนอกไม่จำเป็นต้องรู้ชื่อหรือหน้าที่ของตัวแปรภายในของออพเจ็กต์
จึงไม่จำเป็นต้องรู้รายละเอียดการทำงานภายในของออพเจ็กต์เลย (ไม่ต้องเห็นซอร์สโค้ดของ Student) เพียงแค่รู้ว่ามีเกตเตอร์ / เซตเตอร์อะไรให้เรียกใช้บ้างก็พอ
การใช้เมธอดเซตยังเป็นหลักประกันได้ว่า โค้ดภายนอกจะไม่สามารถเปลี่ยนแปลงค่าภายในของออพเจ็กต์อย่างผิด ๆ
เพราะเราสามารถใส่โค้ดคัดกรองข้อมูลไว้ในเมธอดเซตได้ด้วยดังจะแสดงในตัวอย่างต่อไป
สำหรับตอนนี้มาดูโค้ดเกตเตอร์ / เซตเตอร์แบบสั้นที่สุดก่อน
และยังแสดงให้เห็นความแตกต่างระหว่างตัวแปรแบบฟิลด์กับตัวแปรธรรมดาด้วย
ก่อนจะอ่านคำอธิบายโค้ดขอให้ท่านทำความเข้าใจคำว่า “โค้ดภายใน” และ “โค้ดภายนอก” เสียก่อน
เพราะนี่เป็นแนวคิดแบบวัตถุวิธี ถ้าท่านไม่เข้าใจสองคำนี้ ท่านก็จะไม่เข้าในแนวคิดที่แฝงอยู่ในโค้ดตัวอย่างนี้
ฉากเหตุการณ์ปรกติที่เกิดขึ้นในการพัฒนาแอพลิเกชันซอฟต์แวร์ คือ ท่านนิยามคลาสไว้ (ในตัวอย่างนี้คือคลาส Student) เป็นคลาสที่จะถูกนำไปใช้โดยท่านเอง
หรือโดยนักเขียนโค้ดผู้อื่นในโครงการปัจจุบัน หรือในอนาคตก็ได้ (ตามหลักการนำโค้ดกลับมาใช้ใหม่ (code reusable)
ซึ่งเป็นประโยชน์หลักอย่างหนึ่งในลัทธิวัตถุวิธี) โค้ดทั้งหมดภายในคลาส Student ผู้เขียนจะเรียกว่า “โค้ดภายใน” (ภาษาอังกฤษเรียกว่า internal code หรือ host code)
ส่วนโค้ดที่ (ท่านเองหรือนักเขียนโค้ดผู้อื่นในโครงการปัจจุบันหรืออนาคตเขียน)
เขียนขึ้นเพื่อนำคลาส Student ไปใช้สร้างออพเจ็กต์ (ในตัวอย่างนี้คือคลาส School)
ผู้เขียนจะเรียกว่า “โค้ดภายนอก” (external code หรือ client code)
กล่าวโดยสรุปคือให้ท่านเพ่งเล็งคลาสที่เรากำลังนิยามอยู่เป็นหลัก และให้จินตนาการว่าต่อไปในอนาคตจะมีโค้ดภายนอกมาเรียกหาคลาสนี้เพื่อสร้างออพเจ็กต์
ในตัวอย่างนี้เราจะยึดเอาคลาส Student เป็นศูนย์กลาง โค้ดอื่น ๆ นอกเหนือจากนี้เราจะว่าถือเป็นโค้ดภายนอกทั้งนั้น
โค้ดบรรทัดที่ 3 ถึง 13 คือนิยามคลาส Student ซึ่งเป็นคลาสหลักของตัวอย่างนี้
ส่วนโค้ดบรรทัดที่ 17 ถึง 21 เป็นนิยามคลาส school ซึ่งมีโค้ดที่จะนำคลาส Student ไปสร้างออพเจ็กต์ คลาส Student จึงเป็นโค้ดภายนอก
โค้ดบรรทัดที่ 5 ประกาศตัวแปรชื่อ age เนื่องจากตัวแปรนี้ถูกประกาศไว้นอกเมธอดใด ๆ จึงทำให้มันมีฐานะเป็น “สมาชิกประเภทฟิลด์” (Field member)
โปรดสังเกตว่าผู้เขียนได้กำหนดแอกเซสโมดิไฟเออร์ของมันไว้ให้เป็นแบบไพรเวท (private) ทำให้โค้ดภายนอกไม่สามารถเข้าถึง (อ่านหรือเขียน) ตัวแปรตัวนี้ได้
โค้ดบรรทัดที่ 6 ประกาศตัวแปรชื่อ grade เนื่องจากตัวแปรนี้ถูกประกาศไว้นอกเมธอดใด ๆ จึงทำให้มันมีฐานะเป็นฟิลด์ เช่นเดียวกับ age
โปรดสังเกตว่าผู้เขียนไม่ได้กำหนดแอกเซสโมดิไฟเออร์ของมันไว้ คอมไพเลอร์ (compiler ตัวแปรภาษา)
จะถือว่าตัวแปรนี้เป็นแบบไพรเวทโดยปริยาย มีผลให้โค้ดภายนอกไม่สามารถเข้าถึงตัวแปรตัวนี้ได้เช่นกัน
ฟิลด์ที่เป็นพับบลิก
โค้ดบรรทัดที่ 7 ผู้เขียนประกาศตัวแปรชื่อ name เนื่องจากตัวแปรนี้ถูกประกาศไว้นอกเมธอดใด ๆ จึงทำให้มันมีฐานะเป็นฟิลด์ เช่นเดียวกับ age และ gradeโปรดสังเกตว่าผู้เขียนกำหนดแอกเซสโมดิไฟเออร์ของมันไว้ให้เป็นพับลิก จึงมีผลให้โค้ดภายนอกสามารถเข้าถึงตัวแปรตัวนี้ได้ด้วย
นี่คือตัวอย่างการเขียนโค้ดที่ผิดดังจะอธิบายต่อไป
โค้ดบรรทัดที่ 10 ประกาศตัวแปรชื่อ subject เป็นการประกาศโดยไม่ระบุแอกเซสโมดิไฟเออร์
คอมไพเลอร์จึงถือว่าตัวแปรนี้มีแอกเซสโมดิไฟเออร์เป็นแบบไพรเวทไปโดยปริยาย
และเนื่องจากตัวแปรตัวนี้ถูกประกาศไว้ภายในเมธอด (เมธอด Entroll)
จึงมีผลให้มันมีภาวะเป็นตัวแปรธรรมดา ไม่ใช่ “สมาชิกประเภทฟิลด์” (Field member) เหมือนอย่างตัวแปร age, grade และ name
แล้วตัวแปรธรรมดาต่างจากตัวแปรที่เป็นสมาชิกประเภทฟิลด์อย่างไร คำตอบคือต่างกันที่สโคป (scope) หรือขอบเขตอายุ
ตัวแปรธรรมดาจะมีชีวิตอยู่ภายในเมธอดเท่านั้น
เมื่อเมธอดสิ้นสุดการทำงานลงตัวแปรจะตายไป ขณะที่ฟิลด์มีอายุยืนกว่า คืออายุขัยของมันจะเท่ากับออพเจ็กต์
ฟิลด์จะมีชีวิตอยู่ตราบเท่าที่ออพเจ็กต์ยังมีชีวิตอยู่ และถูกทำลายไปพร้อมกับออพเจ็กต์เมื่อออพเจ็กต์จบชีวิต
ออพเจ็กต์จะตายเมื่อไม่มีโค้ดใด ๆ อ้างถึงมัน และจะถูกนำไปกำจัดโดย “การ์เบจคอลเลคเตอร์” (garbage collector) ต่อไป
เอนเคปซูเลชัน
ต่อไปนี้จะพูดถึงเอสแคปซูเลชันเฉพาะส่วนที่เกี่ยวข้องกับพรอพเพอร์ตีในการออกแบบและเขียนโปรแกรมตามลัทธิวัตถุวิธี (Object Oriented Design/Programming)
มีแนวคิด เอนแคปซูเลชัน (Encapsulation) ที่ไม่ต้องการให้โค้ดภายนอกเข้าถึง ตัวแปรที่เป็นสมาชิกแบบฟิลด์ (field member) ของคลาสอื่นได้โดยตรง
หรือพูดอีกอย่างหนึ่งคือห้ามโค้ดภายนอกยุ่งกับกิจการภายในของคลาสอื่น พูดแบบภาษาหนังสือพิมพ์คือห้าม “ล้วงลูก” นั่นเอง
โค้ดบรรทัดที่ 14 ถึง 21 คือนิยามคลาส school นี่คือคลาสที่จะนำ Student ไปใช้งาน
มันจึงเป็นโค้ดภายนอกเพราะตอนนี้เรากำลังออกแบบสร้างคลาส Student อยู่
เราจึงยึดเอา Student เป็นศูนย์กลางของภาพ ดังนั้นโค้ดบรรทัดที่ 4 ถึง 13 จึงเป็นโค้ดภายใน ส่วนโค้ดอื่น ๆ ถือว่าเป็นโค้ดภายนอกทั้งสิ้น
โค้ดบรรทัดที่ 18 สร้างออพเจ็กต์ (ที่ถูกชี้โดยตัวแปร) ชื่อ myStudent จากคลาส Student
โค้ดบรรทัดที่ 19 เราเปลี่ยนแปลงค่าของตัวแปร name ซึ่งตัวแปรนี้เป็นสมาชิกแบบฟิลด์ (field member) ของออพเจ็กต์
นี่คือการ “ล้วงลูก” เพราะโค้ดในคลาส Student ซึ่งเป็นโค้ดภายนอกเข้าถึง ตัวแปร name ที่เป็นสมาชิกแบบฟิลด์ (field member) ของคลาส Student โดยตรง
นี่คือการกระทำที่ผิดหลักเอนเคปซูเลชัน
ผลของการละเมิดเอนเคปซูเลชัน
การกระทำที่ผิดหลักเอนเคปซูเลชันจะนำมาซึ่งปัญหาหลายอย่าง เช่น- ไม่เป็นกล่องดำ: ผู้เขียนโค้ดภายนอกจะต้องรู้ชื่อและหน้าที่ของตัวแปรภายในของออพเจ็กต์ นั่นคือจะต้องรู้รายละเอียดการทำงานของออพเจ็กต์ นี่เป็นสิ่งที่เราต้องการหลีกเลี่ยงตั้งแต่แรก
- ใครเปลี่ยนค่า: ถ้ามีโค้ดภายนอกหลายตำแหน่ง เปลี่ยนแปลงค่าภายในของออพเจ็กต์ตัวเดียวกัน เราจะไม่รู้แน่ชัดว่าค่าที่เปลี่ยนไปนั้นเกิดจากโค้ดภายนอกอันไหนกันแน่ เหตุการณ์แบบนี้ทำให้ดีบักลำบาก
- ค่าผิด: ไม่มีหลักประกันว่าโค้ดภายนอกจะเปลี่ยนแปลงค่าได้อย่างถูกต้อง เช่นเปลี่ยนค่าอายุของนักเรียนเป็น 500 ซึ่งมากผิดปรกติ
ในภาษาซีพลัสพลัสและจาวาจะใช้วิธีทำ เกตเตอร์ / เซตเตอร์ ส่วนภาษาซีชาร์พก้าวหน้าไปอีกระดับหนึ่ง
เพราะมีกลไกที่เรียกว่า “พรอพเพอร์ตี” ที่มีไว้เพื่อการนี้โดยเฉพาะ
การเชื่อมหลวม
หลักการเอนเคปซูเลชันส่งเสริมแนวคิดการเชื่อมหลวมการออกแบบซอฟต์แวร์ในลัทธิวัตถุวิธี
การเชื่อมหลวม (loose coupling) คือดี
การเชื่อมแน่น (tight coupling) ไม่ดี
การเชื่อมแน่นคือ คลาสสองคลาส (หรือมากกว่า) ขึ้นอยู่แก่กัน เมื่อเราแก้โค้ดในคลาสหนึ่ง จะส่งผลกระทบไปยังอีกคลาสหนึ่ง
ส่วนการเชื่อมหลวมคือเราออกแบบให้ทุกคลาสมีอิสระต่อกัน เมื่อเราเปลี่ยนแปลงโค้ดในคลาสหนึ่ง จะไม่ส่งผลกระทบไปที่ไหนทั้งนั้น
การจะทำให้เกิดการเชื่อมหลวม เราต้องออกแบบให้คลาสหนึ่งคลาสทำหน้าที่เพียงเรื่องเดียว (high cohesion)
และแยกประเด็นไม่ให้พัวกันกัน (separation of concerns) รายละเอียดเรื่องนี้ค่อนข้างยาว ผู้เขียนจะนำเสนอในบทความตอนต่อ ๆ ไป
เกตเตอร์ / เซตเตอร์
เพื่อจะเข้าใจที่มาของพรอพเพอร์ตี ท่านควรจะเข้าใจวิธีทำ เกตเตอร์ / เซตเตอร์เสียก่อน เกตเตอร์ / เซตเตอร์ เป็นเมธอดธรรมดา (ในภาษาภาษาซีพลัสพลัสเรียกว่าฟังก์ชัน) ที่มีวิธีการประกาศเหมือนเมธอดทั่วไป แต่มีจุดมุ่งหมายเพียงประการเดียวคือ “เมธอดเกต” มีไว้เพื่อให้โค้ดภายนอกอ่านค่าภายในของออพเจ็กต์ ส่วน “เมธอดเซต” มีหน้าที่ช่วยให้โค้ดภายนอกเขียน (เปลี่ยนแปลง) ค่าภายในของออพเจ็กต์ได้การให้โค้ดภายนอกอ่านหรือเขียนค่าภายในของออพเจ็กต์ผ่านเมธอดทั้งสองนี้ ช่วยส่งเสริมแนวคิดเอนเคปซูเลชัน
เพราะผู้เขียนโค้ดภายนอกไม่จำเป็นต้องรู้ชื่อหรือหน้าที่ของตัวแปรภายในของออพเจ็กต์
จึงไม่จำเป็นต้องรู้รายละเอียดการทำงานภายในของออพเจ็กต์เลย (ไม่ต้องเห็นซอร์สโค้ดของ Student) เพียงแค่รู้ว่ามีเกตเตอร์ / เซตเตอร์อะไรให้เรียกใช้บ้างก็พอ
การใช้เมธอดเซตยังเป็นหลักประกันได้ว่า โค้ดภายนอกจะไม่สามารถเปลี่ยนแปลงค่าภายในของออพเจ็กต์อย่างผิด ๆ
เพราะเราสามารถใส่โค้ดคัดกรองข้อมูลไว้ในเมธอดเซตได้ด้วยดังจะแสดงในตัวอย่างต่อไป
สำหรับตอนนี้มาดูโค้ดเกตเตอร์ / เซตเตอร์แบบสั้นที่สุดก่อน
โค้ดตัวอย่างในภาพที่สองมีสองคลาสคือ Student และ School เหมือนตัวอย่างที่แล้ว
บรรทัดที่ 3 ถึง 13 คือนิยามคลาส Student ที่เป็นโค้ดภายในของตัวอย่างนี้ ส่วนบรรทัดที่ 15 ถึง 23 คือนิยามคลาส School ที่เป็นโค้ดภายนอกของตัวอย่างนี้
คลาส Student มีสมาชิกสามตัวคือ
โค้ดบรรทัดที่ 20 เรียกเมธอด GetName ซึ่งทำหน้าที่นำค่าจากฟิลด์ name มาเป็นค่าส่งกลับ (บรรทัดที่ 8) ทำให้เมื่อโค้ดบรรทัดที่ 20 ทำงานเสร็จแล้วตัวแปร foo จะมีค่าเป็นข้อความตัวอักษรว่า “Loy” โค้ดบรรทัดที่ 21 เรียกเมธอด SetName โดยส่งค่าเป็นข้อความตัวอักษรว่า “Vanich” เป็นเป็นอาร์กิวเมนต์ให้แก่เมธอด ค่านี้จะไปปรากฏที่พารามิเตอร์ s ในบรรทัดที่ 10 และโค้ดบรรทัดที่ 12 จะนำค่านี้ไปใส่ในฟิลด์ name
แต่ในทางปฏิบัติโค้ดภายนอกก็สามารถเปลี่ยนแปลงค่าภายในออพเจ็กต์ได้อยู่ดี ที่เป็นเช่นนั้นเพราะมันเป็นโค้ดตัวอย่างแบบสั้นที่สุด
คุณประโยชน์ของเกตเตอร์ / เซตเตอร์ จะชัดขึ้นก็ต่อเมื่อเราใส่โค้ดซึ่งทำหน้าที่ประมวลผลไว้ในนั้นด้วย
ยกตัวอย่างเช่น หากเรามีกฎว่าสิ่งที่เก็บในฟิลด์ name จะเป็นข้อความอะไรก็ได้นอกจากความว่างเปล่า
หากไม่มีข้อความอะไรจะเก็บจริง ๆ ให้ใส่คำว่า “Null” เพื่อเป็นเครื่องบ่งชี้ว่ายังไม่มีข้อมูล
แน่นอนว่ากฎนี้อาจถูกเพิกเฉยหรือละเลยจากผู้เขียนโค้ดภายนอกที่อาจจะส่งสตริงว่าง ๆ มาเมื่อใดก็ได้
นี่จะกลายเป็นสาเหตุที่ทำให้เกิดรันทามน์เออเรอร์หรือสร้างปัญหาอื่นในการประมวลผลต่อไป
หากเรายอมให้ผู้เขียนโค้ดภายนอกเปลี่ยนแปลงค่าของ ฟิลด์ name ได้โดยตรงเราจะไม่มีทางป้องกันปัญหานี้ได้
บรรทัดที่ 3 ถึง 13 คือนิยามคลาส Student ที่เป็นโค้ดภายในของตัวอย่างนี้ ส่วนบรรทัดที่ 15 ถึง 23 คือนิยามคลาส School ที่เป็นโค้ดภายนอกของตัวอย่างนี้
คลาส Student มีสมาชิกสามตัวคือ
- Name: ประกาศไว้บรรทัดที่ 5 เป็นสมาชิกแบบฟิลด์ ผู้เขียนกำหนดให้มีแอกเซสโมดิไฟเออร์เป็นแบบไพรเวทเพื่อไม่ให้โค้ดภายนอกมองเห็นหรือเปลี่ยนแปลงค่าได้
- GetName: ประกาศนิยามไว้บรรทัดที่ 6 ถึง 9 เป็นสมาชิกแบบเมธอด ผู้เขียนกำหนดให้มีแอกเซสโมดิไฟเออร์เป็นแบบพับลิก เพื่อให้โค้ดภายนอกมองเห็นและเรียกหาได้ เมธอดนี้ทำหน้าที่เป็นเกตเตอร์
- SetName: ประกาศนิยามไว้บรรทัดที่ 10 ถึง 13 เป็นสมาชิกแบบเมธอด ผู้เขียนกำหนดให้มีแอกเซสโมดิไฟเออร์เป็นแบบพับลิก เพื่อให้โค้ดภายนอกมองเห็นและเรียกหาได้ เมธอดนี้ทำหน้าที่เป็นเซตเตอร์
โค้ดบรรทัดที่ 20 เรียกเมธอด GetName ซึ่งทำหน้าที่นำค่าจากฟิลด์ name มาเป็นค่าส่งกลับ (บรรทัดที่ 8) ทำให้เมื่อโค้ดบรรทัดที่ 20 ทำงานเสร็จแล้วตัวแปร foo จะมีค่าเป็นข้อความตัวอักษรว่า “Loy” โค้ดบรรทัดที่ 21 เรียกเมธอด SetName โดยส่งค่าเป็นข้อความตัวอักษรว่า “Vanich” เป็นเป็นอาร์กิวเมนต์ให้แก่เมธอด ค่านี้จะไปปรากฏที่พารามิเตอร์ s ในบรรทัดที่ 10 และโค้ดบรรทัดที่ 12 จะนำค่านี้ไปใส่ในฟิลด์ name
การคัดกรองข้อมูล
โค้ดแสดงเกตเตอร์ / เซตเตอร์ ในภาพที่สองอาจดูเหมือนเป็นการกระทำที่ไร้สาระ เพราะแม้จะเป็นการกระทำทางอ้อมผ่านเมธอดแต่ในทางปฏิบัติโค้ดภายนอกก็สามารถเปลี่ยนแปลงค่าภายในออพเจ็กต์ได้อยู่ดี ที่เป็นเช่นนั้นเพราะมันเป็นโค้ดตัวอย่างแบบสั้นที่สุด
คุณประโยชน์ของเกตเตอร์ / เซตเตอร์ จะชัดขึ้นก็ต่อเมื่อเราใส่โค้ดซึ่งทำหน้าที่ประมวลผลไว้ในนั้นด้วย
ยกตัวอย่างเช่น หากเรามีกฎว่าสิ่งที่เก็บในฟิลด์ name จะเป็นข้อความอะไรก็ได้นอกจากความว่างเปล่า
หากไม่มีข้อความอะไรจะเก็บจริง ๆ ให้ใส่คำว่า “Null” เพื่อเป็นเครื่องบ่งชี้ว่ายังไม่มีข้อมูล
แน่นอนว่ากฎนี้อาจถูกเพิกเฉยหรือละเลยจากผู้เขียนโค้ดภายนอกที่อาจจะส่งสตริงว่าง ๆ มาเมื่อใดก็ได้
นี่จะกลายเป็นสาเหตุที่ทำให้เกิดรันทามน์เออเรอร์หรือสร้างปัญหาอื่นในการประมวลผลต่อไป
หากเรายอมให้ผู้เขียนโค้ดภายนอกเปลี่ยนแปลงค่าของ ฟิลด์ name ได้โดยตรงเราจะไม่มีทางป้องกันปัญหานี้ได้
แต่ตอนนี้ดีใจได้ เพราะเรายอมให้ผู้เขียนโค้ดภายนอกเปลี่ยนแปลงค่าของฟิลด์ name ผ่านเซตเตอร์เท่านั้น
และเซตเตอร์ก็เป็นเมธอดเหมือนเมธอดธรรมาทั่วไปที่เราจะใส่โค้ดอะไรไว้ในนั้นก็ได้ตามใจชอบ
โค้ดในภาพ 3 เป็นคลาส Student ที่ถูกแก้ไขดัดแปลงเซตเตอร์ให้มีโค้ดที่คัดกรองข้อมูลแล้ว
คำสั่งในบรรทัดที่ 15 ตรวจสอบว่าโค้ดภายนอกส่งสตริงที่ว่างเปล่ามาหรือไม่
ถ้าไม่ โค้ดบรรทัดที่ 16 จะนำค่าที่ได้รับมาไปใส่ในฟิลด์ name แต่ถ้าเป็นสตริงที่ว่างเปล่า
โค้ดบรรทัดที่ 18 จะทำงานเพื่อใส่คำว่า “Null” เข้าไปในฟิลด์ name แทน
ในภาพที่สามโค้ดส่วนเกตเตอร์ (บรรทัดที่ 5 ถึง 12) ก็ถูกดัดแปลงเช่นเดียวกัน
โดยมีโจทย์ว่าเราต้องการให้มันตรวจค่าของฟิลด์ name ก่อนว่าเป็นเป็นสตริงที่ว่างเปล่าหรือไม่ (สมมุตติว่ามีโอกาสเกิดขึ้นได้)
ก่อนที่จะส่งให้โค้ดภายนอก คำสั่งในบรรทัดที่ 8 จะตรวจสอบว่าค่าของฟิลด์ name เป็นสตริงที่ว่างเปล่ามาหรือไม่
ถ้าไม่ โค้ดบรรทัดที่ 9 จะส่งค่านั้นกลับไปให้โค้ดภายนอก แต่ถ้าเป็นสตริงที่ว่างเปล่า
โค้ดบรรทัดที่ 11 จะทำงานเพื่อส่งคำว่า “Null” กลับไปแทน
นอกจากจะเน้นประสิทธิภาพแล้วภาษาซีชาร์พยังเน้นความงามด้วย (ความสง่างามของซอร์สโค้ด)
ผู้สร้างภาษานี้จึงประดิษฐ์พรอพเพอร์ตีเพื่อให้ใช้แทน เกตเตอร์ / เซตเตอร์
ถ้าท่านใช้พรอพเพอร์ตีโค้ดของท่านจะกระชับ อ่านง่าย ดูงามตากว่าการใช้ เกตเตอร์ / เซตเตอร์
พรอพเพอร์ตีปรากฏในภาษาซีชาร์พมาตั้งแต่เวอร์ชันแรก เรียกว่าคลาสสิกพรอพเพอร์ตี
และได้รับการปรับปรุงเปลี่ยนแปลงมาเรื่อยเป็น ออโตพรอพเพอร์ตี (auto implemented properties)
และพรอพเพอร์ตีแบบใส่ Expression-bodied members ที่ผู้เขียนจะพูดถึงในโอกาสต่อไป
ส่วนหัวข้อนี้คือคลาสสิกพรอพเพอร์ตีแบบพื้นฐานที่สุดเท่านั้น
และเซตเตอร์ก็เป็นเมธอดเหมือนเมธอดธรรมาทั่วไปที่เราจะใส่โค้ดอะไรไว้ในนั้นก็ได้ตามใจชอบ
โค้ดในภาพ 3 เป็นคลาส Student ที่ถูกแก้ไขดัดแปลงเซตเตอร์ให้มีโค้ดที่คัดกรองข้อมูลแล้ว
คำสั่งในบรรทัดที่ 15 ตรวจสอบว่าโค้ดภายนอกส่งสตริงที่ว่างเปล่ามาหรือไม่
ถ้าไม่ โค้ดบรรทัดที่ 16 จะนำค่าที่ได้รับมาไปใส่ในฟิลด์ name แต่ถ้าเป็นสตริงที่ว่างเปล่า
โค้ดบรรทัดที่ 18 จะทำงานเพื่อใส่คำว่า “Null” เข้าไปในฟิลด์ name แทน
ในภาพที่สามโค้ดส่วนเกตเตอร์ (บรรทัดที่ 5 ถึง 12) ก็ถูกดัดแปลงเช่นเดียวกัน
โดยมีโจทย์ว่าเราต้องการให้มันตรวจค่าของฟิลด์ name ก่อนว่าเป็นเป็นสตริงที่ว่างเปล่าหรือไม่ (สมมุตติว่ามีโอกาสเกิดขึ้นได้)
ก่อนที่จะส่งให้โค้ดภายนอก คำสั่งในบรรทัดที่ 8 จะตรวจสอบว่าค่าของฟิลด์ name เป็นสตริงที่ว่างเปล่ามาหรือไม่
ถ้าไม่ โค้ดบรรทัดที่ 9 จะส่งค่านั้นกลับไปให้โค้ดภายนอก แต่ถ้าเป็นสตริงที่ว่างเปล่า
โค้ดบรรทัดที่ 11 จะทำงานเพื่อส่งคำว่า “Null” กลับไปแทน
คลาสสิกพรอพเพอร์ตี
การทำ เกตเตอร์ / เซตเตอร์ เป็นการทำความดีในลัทธิวัตถุวิธี แต่ถ้าเรามีฟิลด์ที่ต้องการเกตเซตเป็นจำมาก โค้ดจะยืดยาวรุงรังดูไม่งามตานอกจากจะเน้นประสิทธิภาพแล้วภาษาซีชาร์พยังเน้นความงามด้วย (ความสง่างามของซอร์สโค้ด)
ผู้สร้างภาษานี้จึงประดิษฐ์พรอพเพอร์ตีเพื่อให้ใช้แทน เกตเตอร์ / เซตเตอร์
ถ้าท่านใช้พรอพเพอร์ตีโค้ดของท่านจะกระชับ อ่านง่าย ดูงามตากว่าการใช้ เกตเตอร์ / เซตเตอร์
พรอพเพอร์ตีปรากฏในภาษาซีชาร์พมาตั้งแต่เวอร์ชันแรก เรียกว่าคลาสสิกพรอพเพอร์ตี
และได้รับการปรับปรุงเปลี่ยนแปลงมาเรื่อยเป็น ออโตพรอพเพอร์ตี (auto implemented properties)
และพรอพเพอร์ตีแบบใส่ Expression-bodied members ที่ผู้เขียนจะพูดถึงในโอกาสต่อไป
ส่วนหัวข้อนี้คือคลาสสิกพรอพเพอร์ตีแบบพื้นฐานที่สุดเท่านั้น
ในโค้ดภาพที่ 4 บรรทัดที่ 6 ถึงบรรทัดที่ 10 คือนิยามคลาสสิกพรอพเพอร์ตีแบบสั้นที่สุด
ขอให้ท่านพิจารณาโค้ดนี้เปรียบเทียบกับโค้ดในภาพที่ 2 (เกตเตอร์ / เซตเตอร์ แบบสั้นที่สุด)
เพื่อเทียบกันระหว่างพรอพเพอร์ตีกับเกตเตอร์ / เซตเตอร์ ขอให้ท่านสังเกตความแตกต่างดังนี้
ตารางแสดงความแตกต่างระหว่างพรอพเพอร์ตีกับเกตเตอร์เซตเตอร์
พรอพเพอร์ตีเป็นสิ่งประดิษฐ์ที่ช่วยให้ซอร์สโค้ดดูดีขึ้น (คำเรียกเป็นทางการของการทำเช่นนี้คือ “วากยะเชื่อมหวาน” syntactic sugar เหมือนยาขมเคลือบน้ำตาลเพื่อให้กินได้ง่ายขึ้น)
การใช้พรอพเพอร์ตีไม่ช่วยให้แอพลิเกชันมีประสิทธิภาพเหนือกว่าการใช้เกตเตอร์ / เซตเตอร์
เพราะท้ายที่สุดแล้วคอมไพเลอร์จะแปลพรอพเพอร์ตีเป็นไบต์โค้ดที่ไม่ต่างจากเมธอดเกตเตอร์ / เซตเตอร์มากนัก
เรื่องพรอพเพอร์ตียังไม่จบแค่นี้ ในตอนต่อไปผู้เขียนจะพูดถึงวิธีใส่โค้ดคัดกรองข้อมูลในคลาสสิกพรอพเพอ์ตี
วิธีเขียนและใช้งาน “ออโตพรอพเพอร์ตี” (auto implemented properties)
และ วิธีลดทอนพรอพเพอร์ตีด้วย “นิพจน์ฝังตัว” (Expression-bodied members) ที่ช่วยให้การเขียนโค้ดกระชับมากขึ้นอีก
ขอให้ท่านพิจารณาโค้ดนี้เปรียบเทียบกับโค้ดในภาพที่ 2 (เกตเตอร์ / เซตเตอร์ แบบสั้นที่สุด)
เพื่อเทียบกันระหว่างพรอพเพอร์ตีกับเกตเตอร์ / เซตเตอร์ ขอให้ท่านสังเกตความแตกต่างดังนี้
ตารางแสดงความแตกต่างระหว่างพรอพเพอร์ตีกับเกตเตอร์เซตเตอร์
พรอพเพอร์ตี | เกตเตอร์ / เซตเตอร์ |
ใช้เพียงตัวเดียว | ใช้สองเมธอด |
ไม่มีวงเล็บหลังชื่อ | มีวงเล็บหลังชื่อ |
ใช้คำว่า get / set | ไม่มีคำว่า get / set |
มีคำว่า value | ไม่มีคำว่า value |
เซตเตอร์ ไม่ใช้อาร์กิวเมนต์ | เซตเตอร์ ใช้อาร์กิวเมนต์ |
ข้อควรสังเกตในพรอพเพอร์ตี
- เพื่อให้อ่านและเขียนฟิลด์ได้ ท่านเพียงนิยามพรอพเพอร์ตีหนึ่งพรอพเพอร์ตีก็พอ เพราะภายในหนึ่งพรอพเพอร์ตีสามารถทำหน้าที่ได้ทั้งเซตและเกต
ในขณะที่เกตเตอร์ / เซตเตอร์ เราจำเป็นจะต้องนิยามสองเมธอด อันหนึ่งทำหน้าที่เกต อีกอันทำหน้าที่เซต
ในขณะที่เกตเตอร์ / เซตเตอร์ เราจำเป็นจะต้องนิยามสองเมธอด อันหนึ่งทำหน้าที่เกต อีกอันทำหน้าที่เซต
- พรอพเพอร์ตีไม่มีวงเล็บหลังชื่อ ขณะที่เกตเตอร์ / เซตเตอร์ท่านจำเป็นต้องใส่วงเล็บด้วยเพราะมันเป็นเมธอด
โค้ดภายนอกที่เรียกใช้พรอพเพอร์ตีก็ไม่ต้องใส่วงเล็บด้วย (ดูโค้ดบรรทัดที่ 17 และ 18 ในภาพที่สี่)
โค้ดภายนอกที่เรียกใช้พรอพเพอร์ตีก็ไม่ต้องใส่วงเล็บด้วย (ดูโค้ดบรรทัดที่ 17 และ 18 ในภาพที่สี่)
- คำว่า get และ set เป็นคำเฉพาะของภาษา (key word) ทำหน้าที่ระบุว่าโค้ดในก้อนที่จะตามมาเป็น get หรือ set
- คำว่า value เป็นคำเฉพาะ ทำหน้าที่อ้างถึงค่าที่โค้ดภายนอกส่งมา ในตัวอย่างนี้คือ “Vanich” ในบรรทัดที่ 18
- โค้ดบรรทัดที่ 18 จะเห็นว่าการเซตค่าไม่ต้องใส่ค่าในวงเล็บอย่างที่เป็นในเมธอดเซต
- สมาชิก name กับสมาชิก Name เป็นคนละสิ่งกัน
- ฟิลด์สมาชิก name กับพรอพเพอร์ตี Name ชื่อคล้ายกัน แต่สะกดไม่เหมือนกัน
- ฟิลด์สามาชิก name เขียนด้วยตัวอักษรตัวเล็กทั้งหมด ขณะที่พรอพเพอร์ตี Name สะกดตัวอักษรตัวแรกเป็นตัวใหญ่
นี่เป็นเรื่องสำคัญ เพราะภาษาซีชาร์พเป็นภาษาที่จำแนกความแตกต่างระหว่างตัวอักษรใหญ่-เล็ก (case sensitivity language)
ทำให้คำว่า name กับ Name ถือเป็นคนละคำกัน ในที่นี้เป็นสมาชิกคลาสคนละตัวกัน
นี่เป็นเรื่องสำคัญ เพราะภาษาซีชาร์พเป็นภาษาที่จำแนกความแตกต่างระหว่างตัวอักษรใหญ่-เล็ก (case sensitivity language)
ทำให้คำว่า name กับ Name ถือเป็นคนละคำกัน ในที่นี้เป็นสมาชิกคลาสคนละตัวกัน
- ฟิลด์สามาชิก name ถูกใช้คู่กันกับพรอพเพอร์ตี Name ทำให้มันอยู่ในฐานะ “ฟิลด์สนับสนุน” (backing field)
- การที่ผู้เขียนตั้งชื่อฟิลด์สนับสนุน ให้ตรงกับพรอพเพอร์ตีที่คู่กัน และให้ชื่อพรอพเพอร์ตีมีอักษรแรกเป็นตัวใหญ่ ไม่ไช่เพราะเป็นข้อบังคับของภาษา
ผู้เขียนจะตั้งชื่อพรอพเพอร์ตีตัวนี้ว่า foo หรืออื่น ๆ ก็ได้ โปรแกรมจะคอมไพล์ผ่านโดยไม่มีเออเรอร์ เมื่อรัน การทำงานก็จะไม่มีอะไรแตกต่างกัน
ผู้เขียนจะตั้งชื่อพรอพเพอร์ตีตัวนี้ว่า foo หรืออื่น ๆ ก็ได้ โปรแกรมจะคอมไพล์ผ่านโดยไม่มีเออเรอร์ เมื่อรัน การทำงานก็จะไม่มีอะไรแตกต่างกัน
- การตั้งชื่อฟิลด์สนับสนุนและพรอพเพอร์ตีที่คู่กัน อย่างที่ผู้เขียนทำในตัวอย่างนี้เป็น “ธรรมเนียมปฏิบัติ” (best practice)
เพราะมันมีข้อดีที่ช่วยให้ผู้อ่านโค้ดเข้าใจได้ทันที่ว่าฟิลด์ใดคู่กับพรอพเพอร์ตีใด
เพราะมันมีข้อดีที่ช่วยให้ผู้อ่านโค้ดเข้าใจได้ทันที่ว่าฟิลด์ใดคู่กับพรอพเพอร์ตีใด
พรอพเพอร์ตีเป็นสิ่งประดิษฐ์ที่ช่วยให้ซอร์สโค้ดดูดีขึ้น (คำเรียกเป็นทางการของการทำเช่นนี้คือ “วากยะเชื่อมหวาน” syntactic sugar เหมือนยาขมเคลือบน้ำตาลเพื่อให้กินได้ง่ายขึ้น)
การใช้พรอพเพอร์ตีไม่ช่วยให้แอพลิเกชันมีประสิทธิภาพเหนือกว่าการใช้เกตเตอร์ / เซตเตอร์
เพราะท้ายที่สุดแล้วคอมไพเลอร์จะแปลพรอพเพอร์ตีเป็นไบต์โค้ดที่ไม่ต่างจากเมธอดเกตเตอร์ / เซตเตอร์มากนัก
เรื่องพรอพเพอร์ตียังไม่จบแค่นี้ ในตอนต่อไปผู้เขียนจะพูดถึงวิธีใส่โค้ดคัดกรองข้อมูลในคลาสสิกพรอพเพอ์ตี
วิธีเขียนและใช้งาน “ออโตพรอพเพอร์ตี” (auto implemented properties)
และ วิธีลดทอนพรอพเพอร์ตีด้วย “นิพจน์ฝังตัว” (Expression-bodied members) ที่ช่วยให้การเขียนโค้ดกระชับมากขึ้นอีก