ข้อดีของภาษา C# : Auto-property initializers

ข้อดีของภาษา C# : Auto-property initializers
ให้หลักประกันแก่ค่าเริ่มต้น
ภาษา C# สร้างความอุ่นใจในการใช้งานตัวแปร เพราะ compiler จะกำหนดค่าเริ่มต้นให้ตัวแปรโดยอัตโนมัติขณะที่บางภาษา เช่น C ไม่มีหลักประกันเช่นนี้
ภาษา C# และภาษา C เหมือนกันตรงที่เราไม่สามารถเรียกใช้งานตัวแปรที่ยังไม่ถูกกำหนดค่าได้
การกระทำใด ๆ กับตัวแปรที่ประกาศไว้แล้วแต่ยังไม่ได้กำหนดค่า จะมีผลให้เกิด error ขณะcompile (compile time error)
ข้อกำหนดนี้สร้างความลำบากให้นักเขียนโค้ดภาษา C มานาน เพราะจะต้องไม่ลืมที่จะกำหนดค่าเริ่มต้นให้ตัวแปร หากมีตัวแปรเป็นจำนวนมากก็นับว่าเป็นภาระหนัก
ในภาษา C
compiler จะปฏิบัติต่อค่าของตัวแปรที่ยังไม่ได้กำหนดค่าได้ตามอำเภอใจ
เพราะมาตรฐาน ANSI ไม่ได้ระบุไว้ว่า
ถ้า compiler พบตัวแปรที่ยังไม่ได้กำหนดค่าจะต้องใช้ค่าอะไรเป็นค่าปริยาย
ทำให้ compiler แต่ละตัวมีพฤติกรรมไม่เหมือนกัน
ศัพท์เทคนิคที่ใช้กับกรณีนี้คือ “ผีออกจมูก” (nasal demons) เพราะโปรแกรมเมอร์ต้องผจญกับพฤติกรรมอันคาดเดาไม่ได้ระหว่าง compiler แต่ละตัว จึงได้รับความทุกข์ทรมานราวกับว่ามีผีเข้าออกทางโพรงจมูก
ในภาษา C#
compiler จะกำหนดค่าเริ่มต้นให้แก่ตัวแปรโดยอัตโนมัติ เพื่อป้องกันไม่ให้เกิดปัญหาอย่างในภาษา C
กล่าวโดยย่อคือ ค่าโดยปริยายสำหรับ
- ชนิดข้อมูลกลุ่มจำนวนเต็ม (byte, int) จะเป็นค่า 0
- กลุ่มทศนิยม (float, double) เป็น 0.0
- ตัวอักษรเดียว (char) เป็น ‘\0’
- ส่วนชนิดข้อมูลที่เป็น reference (reference type เช่น string, struct, class) จะให้มีค่าเป็น null
(กรุณาดูรายละเอียดของค่าปริยายสำหรับ data type ชนิดต่าง ๆ จากเอกสารอ้างอิงในเว็บไซต์ของไมโครซอฟท์)
ในภาพคือโค้ดภาษา C# แสดงการใช้งานตัวแปรได้โดยไม่ต้องกำหนดค่าเริ่มต้นก่อน
โค้ดบรรทัดที่ 5-16 คือ นิยามคลาส foo ที่จะถูกใช้เพื่อแสดงให้เห็นว่าเราไม่ต้องกำหนดค่าเริ่มต้นให้แก่ตัวแปร 3 ตัว คือ b, c และ s
บรรทัดที่ 7 ประกาศตัวแปร b
โปรดสังเกตว่านี้ คือ การนิยามโดยไม่ได้กำหนดค่า ชนิดข้อมูล (data type) ของ b เป็น sbyte
เพื่อเป็นตัวแทนชนิดข้อมูลในกลุ่มเลขจำนวนเต็ม (integral type เช่น ushort, int, uint, long) ที่ compiler จะใส่ค่าปริยายเป็นค่าศูนย์
ถัดมาคือประกาศตัวแปร c มีชนิดข้อมูลเป็น char คอมไพเลอร์จะใส่ค่าปริยายเป็น ‘\0’ ซึ่งเป็นรหัส null (null character หรือ null terminator ก็ว่า)
รหัสนี้เป็นมาตรฐานตามตาราง ASCII (ASCII table) ที่กำหนดให้รหัสตัวแรกเป็นค่านี้
ค่า null เป็นโค้ดที่จะไม่ทำให้เกิดปฏิกิริยาใด ๆ กับเครื่องเทอร์มินัล และภาษา C ใช้ค่านี้ปิดท้าย string เพื่อบอกให้รู้ว่า string สิ้นสุดที่ใด
บรรทัดที่ 7 ประกาศตัวแปร b
โปรดสังเกตว่านี้ คือ การนิยามโดยไม่ได้กำหนดค่า ชนิดข้อมูล (data type) ของ b เป็น sbyte
เพื่อเป็นตัวแทนชนิดข้อมูลในกลุ่มเลขจำนวนเต็ม (integral type เช่น ushort, int, uint, long) ที่ compiler จะใส่ค่าปริยายเป็นค่าศูนย์
ถัดมาคือประกาศตัวแปร c มีชนิดข้อมูลเป็น char คอมไพเลอร์จะใส่ค่าปริยายเป็น ‘\0’ ซึ่งเป็นรหัส null (null character หรือ null terminator ก็ว่า)
รหัสนี้เป็นมาตรฐานตามตาราง ASCII (ASCII table) ที่กำหนดให้รหัสตัวแรกเป็นค่านี้
ค่า null เป็นโค้ดที่จะไม่ทำให้เกิดปฏิกิริยาใด ๆ กับเครื่องเทอร์มินัล และภาษา C ใช้ค่านี้ปิดท้าย string เพื่อบอกให้รู้ว่า string สิ้นสุดที่ใด
คำว่าเทอมินัลในที่นี้หมายถึงคอมพิวเตอร์เทอร์มินัล (computer terminal) เป็นอุปกรณ์ที่มีจอภาพและพิมพ์เพื่อเชื่อมต่อทางไกลกับเครื่องคอมพิวเตอร์
ในสมัยที่ภาษา C ถูกสร้าง (ซึ่งเป็นสมัยเดียวกับที่ตาราง ASCII ถูกออกแบบ)
คอมพิวเตอร์เทอมินัลที่มีจอภาพยังไม่ถูกประดิษฐ์ขึ้น จึงใช้เครื่องเทเลไทป์ที่ไม่มีจอ
แต่มีเครื่องพิมพ์ แป้นพิมพ์ และเครื่องเจาะ-อ่านแถบกระดาษ ใช้เพื่อเชื่อมต่อกับเมนเฟรมหรือมินิคอมพิวเตอร์
สาเหตุที่ผู้สร้าง compiler ภาษา C# เลือกใช้ ‘\0’ เพราะ null character ในภาษา C ใช้รหัสเดียวกันนี้
ในสมัยที่ภาษา C ถูกสร้าง (ซึ่งเป็นสมัยเดียวกับที่ตาราง ASCII ถูกออกแบบ)
คอมพิวเตอร์เทอมินัลที่มีจอภาพยังไม่ถูกประดิษฐ์ขึ้น จึงใช้เครื่องเทเลไทป์ที่ไม่มีจอ
แต่มีเครื่องพิมพ์ แป้นพิมพ์ และเครื่องเจาะ-อ่านแถบกระดาษ ใช้เพื่อเชื่อมต่อกับเมนเฟรมหรือมินิคอมพิวเตอร์
สาเหตุที่ผู้สร้าง compiler ภาษา C# เลือกใช้ ‘\0’ เพราะ null character ในภาษา C ใช้รหัสเดียวกันนี้

บรรทัดที่ 9 ประกาศตัวแปร s ซึ่งมีชนิดข้อมูลเป็น string
ทำหน้าที่เป็นตัวแทนชนิดข้อมูลแบบ reference (reference type) ซึ่งเป็นตัวแปรทำหน้าที่อ้างอิงไปยังออพเจ็กต์
สาเหตุที่ string เป็นreference type เพราะในภาษา C# String เป็นออพเจ็กที่เกิดจากคลาส String
ตัวแปรแบบ string จึงไม่ได้เก็บข้อมูลโดยตรง แต่เก็บค่าอ้างอิงไปยังออพเจ็กต์ (ทำหน้าที่เหมือน ponter ในภาษา C)
เมื่อเราประกาศตัวแปรแบบ string โดยไม่ได้กำหนดค่า compiler จะกำหนดค่าโดยปริยายให้เป็น null
นั่นคือไม่ได้ชี้ไปยังออพเจ็กต์ใด ๆ (เพราะในขณะนั้นยังไม่มีออพเจ็กต์ที่จะให้ชี้ไป)
บรรทัดที่ 10-15 คือนิยาม method test()
โค้ดภายใน method นี้ (บรรทัด 12-14) อ้างถึงตัวแปรทั้ง 3 โดยใช้ method Console.WriteLine() เพื่อแสดงค่าของมันที่ console
ถ้าเป็นภาษา C การทำเช่นนี้ คือ การเรียกใช้ตัวแปรที่ยังไม่ได้กำหนดค่า จะเป็นเหตุให้เกิด Error เมื่อ compile
แต่ในภาษา C# จะ compile และ run ได้โดยไม่เกิด error เพราะตัวแปรทั้ง 3 ถูกกำหนดค่าโดยปริยายไว้แล้ว
โค้ดบรรทัด 19-23 method Main นำคลาส foo มาสร้างออพเจ็กต์และเรียกใช้ method test() ของ foo
จากที่กล่าวข้างต้น จะเห็นว่า ภาษา C# ดีกว่า ภาษา C ในการป้องกันการเกิด error ขณะ compile (compile time error)
เนื่องจาก ภาษา C# สร้างความอุ่นใจในการใช้งานตัวแปร เพราะ compiler จะกำหนดค่าเริ่มต้นให้ตัวแปรโดยอัตโนมัติครับ
ทำหน้าที่เป็นตัวแทนชนิดข้อมูลแบบ reference (reference type) ซึ่งเป็นตัวแปรทำหน้าที่อ้างอิงไปยังออพเจ็กต์
สาเหตุที่ string เป็นreference type เพราะในภาษา C# String เป็นออพเจ็กที่เกิดจากคลาส String
ตัวแปรแบบ string จึงไม่ได้เก็บข้อมูลโดยตรง แต่เก็บค่าอ้างอิงไปยังออพเจ็กต์ (ทำหน้าที่เหมือน ponter ในภาษา C)
เมื่อเราประกาศตัวแปรแบบ string โดยไม่ได้กำหนดค่า compiler จะกำหนดค่าโดยปริยายให้เป็น null
นั่นคือไม่ได้ชี้ไปยังออพเจ็กต์ใด ๆ (เพราะในขณะนั้นยังไม่มีออพเจ็กต์ที่จะให้ชี้ไป)
บรรทัดที่ 10-15 คือนิยาม method test()
โค้ดภายใน method นี้ (บรรทัด 12-14) อ้างถึงตัวแปรทั้ง 3 โดยใช้ method Console.WriteLine() เพื่อแสดงค่าของมันที่ console
ถ้าเป็นภาษา C การทำเช่นนี้ คือ การเรียกใช้ตัวแปรที่ยังไม่ได้กำหนดค่า จะเป็นเหตุให้เกิด Error เมื่อ compile
แต่ในภาษา C# จะ compile และ run ได้โดยไม่เกิด error เพราะตัวแปรทั้ง 3 ถูกกำหนดค่าโดยปริยายไว้แล้ว
โค้ดบรรทัด 19-23 method Main นำคลาส foo มาสร้างออพเจ็กต์และเรียกใช้ method test() ของ foo
จากที่กล่าวข้างต้น จะเห็นว่า ภาษา C# ดีกว่า ภาษา C ในการป้องกันการเกิด error ขณะ compile (compile time error)
เนื่องจาก ภาษา C# สร้างความอุ่นใจในการใช้งานตัวแปร เพราะ compiler จะกำหนดค่าเริ่มต้นให้ตัวแปรโดยอัตโนมัติครับ