Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C#

การส่งพารามิเตอร์แบบ Pass by Value ใน C#

ภาพรวม

Pass by Value (การส่งค่า) เป็นกลไกเริ่มต้น (Default) ของ C# เมื่อส่งพารามิเตอร์เข้าเมธอด จะสร้าง ตำแหน่งหน่วยความจำใหม่ และ คัดลอกค่า จากตัวแปรจริง (Argument) ไปยังพารามิเตอร์ (Parameter) การเปลี่ยนแปลงพารามิเตอร์ภายในเมธอด ไม่ส่งผลต่อ ตัวแปรต้นฉบับ

ตัวอย่างโปรแกรม: Sw แบบ Pass by Value

using System;

namespace CalculatorApplication
{
    class NumberManipulator
    {
        public void Swap(int x, int y)
        {
            int temp = x;
            x = y;
            y = temp;
            Console.WriteLine("ในเมธอด Swap: x={0}, y={1}", x, y);
        }
        
        static void Main(string[] args)
        {
            NumberManipulator n = new NumberManipulator();
            int a = 100;
            int b = 200;
            
            Console.WriteLine("ก่อน Swap: a={0}, b={1}", a, b);
            n.Swap(a, b);  // ส่งค่า (Copy)
            Console.WriteLine("หลัง Swap: a={0}, b={1}", a, b);
            
            Console.ReadLine();
        }
    }
}

ผลลัพธ์

ก่อน Swap: a=100, b=200
ในเมธอด Swap: x=200, y=100
หลัง Swap: a=100, b=200

ค่า a, b ไม่เปลี่ยน เพราะส่งเป็น Copy

แผนภาพหน่วยความจำ

Main Stack Frame:          Swap Stack Frame:
┌─────────┐                  ┌─────────┐
│ a: 100  │   ───Copy───▶    │ x: 100  │ ──Swap──▶ │ x: 200 │
├─────────┤                  ├─────────┤           ├─────────┤
│ b: 200  │   ───Copy───▶    │ y: 200  │ ──Swap──▶ │ y: 100 │
└─────────┘                  └─────────┘           └─────────┘

หลัง Swap กลับมา: a=100, b=200 (ไม่เปลี่ยน)

พฤติกับกับ Reference Types (Class, Array, String)

แม้จะเป็น Pass by Value แต่ถ้าพารามิเตอร์เป็น Reference Type จะ Copy Reference (Address) ไป → สามารถแก้ไข เนื้อหา Object ได้ แต่ ไม่สามารถเปลี่ยน Reference ของตัวแปรต้นฉบับได้

void Modify(StringBuilder sb)
{
    sb.Append(" World"); // แก้ไขเนื้อหา Object ได้ ✓
    sb = new StringBuilder("New"); // เปลี่ยน Reference ตัวแปร Parameter เท่านั้น ✗
}

StringBuilder s = new StringBuilder("Hello");
Modify(s);
Console.WriteLine(s); // "Hello World" - เนื้อหาเปลี่ยน!

Pass by Value vs Pass by Reference

คุณสมบัติPass by Value (Default)Pass by Reference (ref/out)
คีย์เวิร์ด(ไม่มี)ref / out / in
Value Types (int, struct)Copy ค่าReference ตัวแปรจริง
Reference Types (class)Copy ReferenceReference ตัวแปรจริง
แก้ไขค่า Parameterไม่ส่งผลต่อ Argumentส่งผลต่อ Argument
แก้ไข Object เนื้อหาได้ (ถ้าเป็น Ref Type)ได้

ข้อสังเกตสำคัญ

  • ค่าเริ่มต้นของ C# คือ Pass by Value เสมอ
  • Struct ใหญ่ๆ การส่งแบบ Value อาจช้า (Copy มาก) → ใช้ in (readonly reference) หรือ ref
  • String เป็น Immutable - Pass by Value ปลอดภัย เพราะแก้ไขไม่ได้
  • การออกแบบ API: ควรใช้ Pass by Value สำหรับ Input ที่ไม่ต้องแก้ไข ใช้ ref/out เมื่อต้องการให้เมธอดเปลี่ยนค่าตัวแปรจริง