Ref keyword
ขวัญปีใหม่ พึ่งไชย 650710531
ในที่นี้เราจะมาพูดถึง ref
keyword ในภาษา C# เราจะใช้ตัวแปร ref
เพื่อส่งค่าไปยังเมธอดหรือรับค่าจากเมธอด ซึ่งหมายความว่า เมธอดสามารถเปลี่ยนแปลงค่าของพารามิเตอร์ได้โดยตรงเมื่อแก้ไขค่าที่มีการจองพื้นที่อยู่ก่อนแล้ว เมื่อใช้ ref
การแก้ไขค่าภายในเมธอดจะส่งผลต่อค่าจริงในหน่วยความจำทันที ทำให้ไม่ต้องคัดลอกข้อมูล ช่วยให้โค้ดทำงานเร็วขึ้น โดยเฉพาะกับข้อมูลขนาดใหญ่
📄 การใช้งาน ref
ref
การประกาศ
ต้องประกาศตัวแปร
ref
ไว้ด้านหน้าพารามิเตอร์ของเมธอดต้องประกาศตัวแปร
ref
ไว้ด้านหน้าตัวแปรที่ประกาศไว้ตอนการเรียกใช้เมธอด
การเปลี่ยนแปลงค่า
ถ้าส่งพารามิเตอร์เข้าไปในเมธอดด้วย
ref
เมธอดนั้นจะสามารถเปลี่ยนแปลงค่าของตัวแปรต้นฉบับได้โดยตรง
💻 การใช้ ref
ref
สามารถใช้ ref
ได้ในกรณีต่อไปนี้:
1. ส่งอาร์กิวเมนต์ไปยังเมธอดโดยการอ้างอิงถึงตัวแปรนั้น
(To pass an argument to a method by its reference) ซึ่งการใช้ ref
จะอนุญาตให้เมธอดนั้นแก้ไขค่าของตัวแปรต้นฉบับได้
Output
2. กำหนดลายเซ็นของเมธอดให้ส่งคืนอ้างอิงของตัวแปร
(To define a method signature to return a reference of the variable) การทำให้เมธอดสามารถส่งคืนตำแหน่งในหน่วยความจำของตัวแปรได้แทนที่จะส่งคืนแค่ค่าของตัวแปรนั้น
Output
3. ประกาศโครงสร้างเป็น ref struct
ref struct
(To declare a struct as a ref struct) การประกาศ ref struct
จะช่วยให้มั่นใจว่าโครงสร้างนี้จะถูกเก็บใน stack เท่านั้น การที่โครงสร้างอยู่ใน stack จะช่วยลดภาระในการจัดการหน่วยความจำและทำให้การเข้าถึงข้อมูลรวดเร็วขึ้น
Output
4. การอ้างอิงในท้องถิ่น
(As local reference) การสร้างตัวแปรที่เชื่อมโยงกับตัวแปรอื่นภายในพื้นที่เดียวกัน ถ้าเราเปลี่ยนแปลงค่าของตัวแปรที่เชื่อมโยง ตัวแปรเดิมก็จะเปลี่ยนไปด้วย
Output
⚠️ ข้อควรระวัง
ต้องกำหนดค่าเริ่มต้น: ตัวแปรที่ส่งเข้าไปโดยใช้
ref
ต้องมีค่าเริ่มต้นก่อน ไม่งั้นจะเกิดปัญหาต้องใช้คำสำคัญในทั้งสองที่: เมื่อเราประกาศพารามิเตอร์ในเมธอดก็ต้องใช้
ref
และเมื่อเราจะเรียกใช้เมธอดก็ต้องใส่ref
ด้วยเช่นกัน
การใช้
ref
ใน C# ช่วยให้เราสามารถส่งพารามิเตอร์โดยอ้างอิง พร้อมเปลี่ยนแปลงค่าตัวแปรต้นฉบับได้ เพิ่มประสิทธิภาพในการจัดการข้อมูลขนาดใหญ่ได้เร็วขึ้น
🆚 เปรียบเทียบกับภาษา Java/C/Python
การใช้คีย์เวิร์ด ref
ใน C# เป็นการส่งผ่านค่าผ่านการอ้างอิง (pass by reference) ซึ่งมีความแตกต่างจากการส่งผ่านค่าปกติ (pass by value) ที่เป็นการส่งค่าจากตัวแปรไปยังฟังก์ชันหรือเมธอดอื่น ๆ ในรูปแบบที่ค่าตัวแปรนั้นถูกส่งตรงตามที่อยู่ในหน่วยความจำ ไม่ใช่ค่าสำเนาของตัวแปรนั้น ๆ
การทำงานของ ref
ใน C#
ref
ใน C#ใน C# การใช้
ref
จำเป็นต้องใช้ทั้งในตอนที่เรียกใช้และตอนที่ประกาศฟังก์ชัน เพื่อบอกว่าอาร์กิวเมนต์ถูกส่งผ่านโดยการอ้างอิงเมื่อส่งตัวแปรไปยังฟังก์ชันด้วย
ref
การเปลี่ยนแปลงในตัวแปรภายในฟังก์ชันจะสะท้อนผลกลับมายังตัวแปรที่ส่งไป
Output
การเปรียบเทียบกับภาษาอื่น ๆ
1. Java
เมื่อเราส่งผ่านการอ้างอิง (pass by reference) หมายความว่า เราส่ง "ตัวจริง" ของออบเจ็กต์เข้าไปในฟังก์ชัน ไม่ได้ส่งสำเนา เมื่อฟังก์ชันทำอะไรกับออบเจ็กต์นั้น เช่น เปลี่ยนค่าในออบเจ็กต์ ค่าที่ถูกเปลี่ยนจะมีผลกับตัวจริงเลย เพราะทั้งตัวที่ส่งเข้าไปและตัวที่ใช้ในฟังก์ชันต่างก็ชี้ไปที่ออบเจ็กต์เดียวกัน ไม่ได้แยกกันทำงาน
ดังนั้น ถ้าเราส่งออบเจ็กต์ไปฟังก์ชันแล้วไปเปลี่ยนค่าอะไรในนั้น ค่าในตัวจริงก็จะเปลี่ยนตามไปด้วย
เพราะฉะนั้น ใน Java ไม่มีคีย์เวิร์ดเฉพาะแบบ ref
เพราะ Java ใช้การส่งค่าตัวแปรแบบ pass-by-value ในทุกกรณี แต่หากส่งออบเจ็กต์จะเป็นการส่งที่อยู่ของออบเจ็กต์นั้น (pass-by-reference) คล้ายกับการใช้งาน ref
ใน C#
Output
2. C
ในภาษา C สามารถทำสิ่งที่คล้ายกับ ref
ได้ด้วยการใช้ pointer (ตัวชี้) ซึ่งเป็นการส่งตัวแปรผ่านการอ้างอิงที่ตรงไปตรงมา
Output
3. Python
Python ส่งผ่านค่าตัวแปรแบบ pass-by-object-reference ซึ่งมีลักษณะคล้ายกับการ pass-by-reference ใน C# เมื่อทำการส่งออบเจ็กต์ (เช่น list หรือ dictionary) แต่หากส่งค่าที่เป็น immutable (เช่น integer, string) จะคล้ายกับ pass-by-value
รูปแบบการส่งอาร์กิวเมนต์ของ Python ไม่ใช่ “Pass by Value” หรือ “Pass by Reference” แต่เป็น “Pass by Object Reference”
Output
สรุป
C#: ใช้
ref
สำหรับ pass-by-reference ทั้งการประกาศและการเรียกฟังก์ชันJava: ไม่มี
ref
โดยตรง แต่การส่งออบเจ็กต์มีลักษณะคล้ายการ pass-by-referenceC: ใช้ pointer เพื่อส่งผ่านค่าผ่านการอ้างอิง
Python: ใช้การส่งผ่านออบเจ็กต์ (pass-by-object-reference) ขึ้นอยู่กับชนิดข้อมูล
การใช้
ref
ทำให้ควบคุมการส่งผ่านค่าผ่านการอ้างอิงได้ชัดเจนขึ้นใน C#
🎞️Presentation
📚 แหล่งที่มา
1. GeeksforGeeks. (July 16, 2021). Ref in C#.
Retrieved from https://www.geeksforgeeks.org/ref-in-c-sharp/
2. Microsoft. (January 8, 2024). Ref keyword.
Retrieved from https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/ref
3. TutorialsTeacher. (January 7, 2020). Ref keyword.
Retrieved from https://www.tutorialsteacher.com/articles/ref-keyword
4. Microsoft. (July 30, 2024). Ref struct.
Retrieved fromhttps://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/ref-struct
GeeksforGeeks. (October 17, 2022). Different Ways to Achieve Pass By Reference in Java.
Retrieved from https://www.geeksforgeeks.org/different-ways-to-achieve-pass-by-reference-in-java/
GeeksforGeeks. (July 24, 2024). C Pointers.
Retrieved from https://www.geeksforgeeks.org/c-pointers/
GeeksforGeeks. (August 9, 2024). Pass by reference vs value in Python.
Retrieved from https://www.geeksforgeeks.org/pass-by-reference-vs-value-in-python/
Last updated