แบบฝึกหัด - ใช้ค่าและพารามิเตอร์ชนิดการอ้างอิง

เสร็จสมบูรณ์เมื่อ

ใน C# ตัวแปรสามารถจัดประเภทเป็นสองชนิดหลัก ชนิดค่า และชนิดการอ้างอิง ชนิดเหล่านี้อธิบายวิธีที่ตัวแปรจัดเก็บค่า

ชนิดค่า เช่น int, bool, float, doubleและ char จะมีค่าโดยตรง ชนิดการอ้างอิง เช่น string, arrayและ ออบเจ็กต์ (เช่น อินสแตนซ์ของ Random) ไม่ได้จัดเก็บค่าไว้โดยตรง แต่ชนิดการอ้างอิงจะจัดเก็บที่อยู่ที่มีการจัดเก็บค่าไว้แทน

พารามิเตอร์ที่ส่งผ่านโดยค่าและส่งผ่านโดยการอ้างอิง

เมื่ออาร์กิวเมนต์ถูกส่งผ่านไปยังเมธอด ตัวแปรชนิด ค่า จะมีค่าที่คัดลอกไปยังเมธอด ตัวแปรแต่ละตัวจะมีสําเนาของค่าของตัวเอง ดังนั้นตัวแปรต้นฉบับจะไม่ถูกปรับเปลี่ยน

ด้วยชนิดการอ้างอิง ที่อยู่ของค่าจะถูกส่งผ่านไปยังเมธอด ตัวแปรที่กําหนดให้กับเมธอด จะอ้างอิงค่า ที่ที่อยู่นั้น ดังนั้นการดําเนินการบนตัวแปรนั้นจะส่งผลกระทบต่อค่าที่อ้างอิงโดยอีกรายการหนึ่ง

หมายเหตุ

สิ่งสําคัญคือต้องจําไว้ว่าstringเป็นประเภทการอ้างอิง แต่ไม่สามารถเปลี่ยนได้ ซึ่งหมายความว่าเมื่อได้รับการกําหนดค่าแล้ว จะไม่สามารถเปลี่ยนแปลงได้ ใน C# เมื่อมีการใช้วิธีการ และ ตัวดําเนินการ เพื่อปรับเปลี่ยนสตริง ผลลัพธ์ที่เป็นผลลัพธ์ที่ส่งกลับแท้จริงแล้วเป็นออบเจ็กต์สตริงใหม่

ในแบบฝึกหัดนี้ คุณจะได้เรียนรู้เพิ่มเติมเกี่ยวกับการส่งผ่านการอ้างอิงและอาร์กิวเมนต์ชนิดค่าไปยังวิธีการ

ทดสอบการส่งผ่านตามค่า

  1. ใน Visual Studio Code Editor ให้ลบโค้ดที่มีอยู่ออกจากแบบฝึกหัดก่อนหน้า

  2. ป้อนรหัสต่อไปนี้ลงในตัวแก้ไขรหัส Visual Studio:

    int a = 3;
    int b = 4;
    int c = 0;
    
    Multiply(a, b, c);
    Console.WriteLine($"global statement: {a} x {b} = {c}");
    
    void Multiply(int a, int b, int c) 
    {
        c = a * b;
        Console.WriteLine($"inside Multiply method: {a} x {b} = {c}");
    }
    

    ตัวแปร a, bและ c จะถูกส่งผ่านไปยัง Multiply วิธีการ ระบบจะพิมพ์ค่าของตัวแปรในระหว่างการดําเนินการวิธีการ และพิมพ์อีกครั้งหลังจากวิธีการ เสร็จสมบูรณ์

    จํานวนเต็มเป็นชนิดค่าที่มีค่าที่คัดลอกเมื่อส่งผ่านไปยังวิธีการ คุณคิดว่าผลลัพธ์ของ c จะเป็นอย่างไร

  3. บันทึกและเรียกใช้โค้ดของคุณเพื่อสังเกตผลลัพธ์ต่อไปนี้:

    inside Multiply method: 3 x 4 = 12
    global statement: 3 x 4 = 0
    

    โปรดสังเกตว่าค่าของ c จะ Multiply มีการเปลี่ยนแปลงภายในเมธอด เท่านั้น ภายนอกวิธีการ จะ c เก็บค่าเดิมไว้

การทดสอบผ่านโดยการอ้างอิง

  1. ลบโค้ดก่อนหน้านี้จาก Visual Studio Code Editor

  2. ป้อนรหัสต่อไปนี้ลงในตัวแก้ไขรหัส Visual Studio:

    int[] array = {1, 2, 3, 4, 5};
    
    PrintArray(array);
    Clear(array);
    PrintArray(array);
    
    void PrintArray(int[] array) 
    {
        foreach (int a in array) 
        {
            Console.Write($"{a} ");
        }
        Console.WriteLine();
    }
    
    void Clear(int[] array) 
    {
        for (int i = 0; i < array.Length; i++) 
        {
            array[i] = 0;
        }
    }
    

    รหัสเริ่มต้นด้วย array การเตรียมใช้งานเพื่อให้มีค่าจํานวนเต็มบางอย่าง ค่าจะแสดงโดยใช้ PrintArray วิธีการ มีการ Clear เรียกใช้เมธอด ในอาร์เรย์ จากนั้นอาร์เรย์จะถูกพิมพ์อีกครั้ง

    อาร์เรย์ เป็นชนิดการอ้างอิง ชนิดการอ้างอิงจะจัดเก็บที่อยู่ของค่าในหน่วยความจํา คุณคิดว่าผลลัพธ์จะเป็นอย่างไร

  3. บันทึกและเรียกใช้โค้ดของคุณเพื่อสังเกตผลลัพธ์ต่อไปนี้:

    1 2 3 4 5 
    0 0 0 0 0
    

    โปรดสังเกตว่าอาร์เรย์ ยังคงถูกเปลี่ยนแปลงอยู่ภายนอก Clear ขอบเขตของเมธอด สิ่งนี้เกิดขึ้นเนื่องจากวิธีการ อัปเดต Clear ค่าที่จัดเก็บไว้ในแต่ละที่อยู่

ทดสอบด้วยสตริง

ก่อนหน้านี้คุณได้เรียนรู้ว่าสตริงเป็นประเภทที่ไม่สามารถเปลี่ยนได้ แม้ว่าสตริงจะเป็นชนิดอ้างอิง แต่ค่าของสตริงจะไม่สามารถเปลี่ยนแปลงได้เมื่อกําหนดแล้ว ซึ่งแตกต่างจากอาร์เรย์ คุณอาจสังเกตเห็นสิ่งนี้ถ้าคุณได้ใช้วิธีการ เช่น string.Replace หรือstring.ToUpper ในงานนี้ คุณจะได้เรียนรู้วิธีการแก้ไขข้อผิดพลาดที่พบเมื่อทํางานกับสตริง

  1. ใน Visual Studio Code Editor ให้ลบโค้ดที่มีอยู่ออกจากแบบฝึกหัดก่อนหน้า

  2. ป้อนรหัสต่อไปนี้ลงในตัวแก้ไขรหัส Visual Studio:

    string status = "Healthy";
    
    Console.WriteLine($"Start: {status}");
    SetHealth(status, false);
    Console.WriteLine($"End: {status}");
    
    void SetHealth(string status, bool isHealthy) 
    {
        status = (isHealthy ? "Healthy" : "Unhealthy");
        Console.WriteLine($"Middle: {status}");
    }
    
  3. บันทึกและเรียกใช้โค้ดของคุณเพื่อสังเกตผลลัพธ์ต่อไปนี้:

    Start: Healthy
    Middle: Unhealthy
    End: Healthy
    

    SetHealthถ้าเมธอด ไม่ได้แสดงสถานะ คุณอาจสันนิษฐานว่าวิธีการ ไม่ได้ทํางานอย่างถูกต้อง แต่สตริงใหม่ที่มีค่า "ไม่แข็งแรง" ถูกสร้างขึ้นและสูญหายในขอบเขตของเมธอด

    เมื่อต้องการแก้ไขปัญหานี้ คุณสามารถเปลี่ยน SetHealth เพื่อใช้ตัวแปรสถานะส่วนกลางแทน

  4. อัปเดตโค้ดของคุณดังต่อไปนี้:

    string status = "Healthy";
    
    Console.WriteLine($"Start: {status}");
    SetHealth(false);
    Console.WriteLine($"End: {status}");
    
    void SetHealth(bool isHealthy) 
    {
        status = (isHealthy ? "Healthy" : "Unhealthy");
        Console.WriteLine($"Middle: {status}");
    }
    

    ในรหัสนี้ คุณเขียนทับตัวแปรส่วนกลาง status ด้วยค่าสตริงใหม่

  5. บันทึกและเรียกใช้โค้ดของคุณเพื่อสังเกตผลลัพธ์ต่อไปนี้:

    Start: Healthy
    Middle: Unhealthy
    End: Unhealthy
    

    ในตอนนี้ สตริงที่อัปเดตถูกบันทึกและจัดเก็บอย่างถูกต้อง

สรุป

นี่คือสิ่งที่คุณได้เรียนรู้เกี่ยวกับชนิดของค่าและพารามิเตอร์ชนิดการอ้างอิงจนถึงตอนนี้:

  • ตัวแปรสามารถจัดประเภทเป็นชนิดค่าและชนิดการอ้างอิงได้
  • ชนิดค่าประกอบด้วยค่าโดยตรง และชนิดการอ้างอิงจะจัดเก็บที่อยู่ของค่า
  • วิธีการที่ใช้อาร์กิวเมนต์ชนิดค่า จะสร้างสําเนาของค่าของตนเอง
  • วิธีการที่ทําการเปลี่ยนแปลงในพารามิเตอร์อาร์เรย์ จะมีผลต่ออาร์เรย์ป้อนเข้าเดิม
  • สตริงเป็นชนิดการอ้างอิงที่ไม่เปลี่ยนได้
  • วิธีการที่ทําการเปลี่ยนแปลงในพารามิเตอร์สตริงไม่มีผลต่อสตริงเดิม