0Pricing
C# Academy · บทเรียน

ชนิดค่าเทียบกับชนิดอ้างอิง

ดูวิธีจัดเก็บและคัดลอกของแต่ละชนิด

ชนิดค่าเทียบกับชนิดอ้างอิง เป็นบทเรียน C# Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C# Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C# Academy มีบทเรียนทั้งหมด 4 บทเรียน

ชนิดข้อมูลสองตระกูล

ชนิดข้อมูลใน C# แบ่งเป็นชนิดค่า ได้แก่ int, double, บูลีน และโครงสร้าง กับชนิดอ้างอิง ได้แก่ คลาส สตริง และอาร์เรย์ ทั้งสองแบบแตกต่างกันในวิธีจัดเก็บและคัดลอก

using System;

class Program
{
    static void Main()
    {
        int valueType = 5;          // value type
        int[] referenceType = { 1, 2, 3 };  // reference type
        Console.WriteLine(valueType + ", length " + referenceType.Length);
    }
}

ชนิดค่าบรรจุข้อมูลไว้โดยตรง

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

using System;

class Program
{
    static void Main()
    {
        int a = 10;
        double b = 3.14;
        bool c = true;
        Console.WriteLine(a + ", " + b + ", " + c);
    }
}

ชนิดอ้างอิงเก็บที่อยู่

ตัวแปรชนิดอ้างอิงจะเก็บการอ้างอิงหรือที่อยู่ของข้อมูลที่จัดเก็บอยู่บนฮีป ตัวแปรกับอ็อบเจ็กต์จึงเป็นคนละส่วนกัน

using System;

class Box { public int Value; }

class Program
{
    static void Main()
    {
        Box b = new Box();   // b refers to a heap object
        b.Value = 42;
        Console.WriteLine(b.Value);
    }
}

ความหมายของการคัดลอก: ชนิดค่า

การกำหนดค่าชนิดค่าจะเป็นการคัดลอกข้อมูล การเปลี่ยนแปลงสำเนาจะไม่ส่งผลต่อต้นฉบับ

using System;

class Program
{
    static void Main()
    {
        int a = 1;
        int b = a;   // copy
        b = 99;
        Console.WriteLine("a=" + a + ", b=" + b);
    }
}

ความหมายของการคัดลอก: ชนิดอ้างอิง

การกำหนดค่าชนิดอ้างอิงจะคัดลอก การอ้างอิง ไม่ใช่ออบเจ็กต์ หลังจากนั้นตัวแปรทั้งสองจะชี้ไปยังออบเจ็กต์เดียวกัน

using System;

class Box { public int Value; }

class Program
{
    static void Main()
    {
        Box a = new Box { Value = 1 };
        Box b = a;   // same object
        b.Value = 99;
        Console.WriteLine("a.Value=" + a.Value + ", b.Value=" + b.Value);
    }
}

โครงสร้างเป็นชนิดค่า

struct ที่คุณกำหนดเป็นชนิดค่า ดังนั้นเมื่อกำหนดค่าจึงถูกคัดลอกเช่นเดียวกับ int

using System;

struct Point { public int X, Y; }

class Program
{
    static void Main()
    {
        Point p1 = new Point { X = 1, Y = 2 };
        Point p2 = p1;   // full copy
        p2.X = 99;
        Console.WriteLine("p1.X=" + p1.X + ", p2.X=" + p2.X);
    }
}

การส่งค่าให้เมธอด

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

using System;

class Counter { public int N; }

class Program
{
    static void BumpInt(int x) { x++; }
    static void BumpObj(Counter c) { c.N++; }

    static void Main()
    {
        int i = 0;
        BumpInt(i);
        var c = new Counter();
        BumpObj(c);
        Console.WriteLine("i=" + i + ", c.N=" + c.N);
    }
}

ค่าที่ไม่มีและชนิดอ้างอิง

เฉพาะชนิดอ้างอิงเท่านั้นที่เป็น null ได้ (หมายถึงไม่มีออบเจ็กต์อยู่) ส่วนชนิดค่าจะมีค่าอยู่เสมอ เว้นแต่จะประกาศให้รองรับค่าว่างด้วย ?

using System;

class Program
{
    static void Main()
    {
        string text = null;        // reference type can be null
        int? maybe = null;          // nullable value type
        Console.WriteLine((text == null) + ", " + (maybe == null));
    }
}

ความแตกต่างของการเท่ากัน

สำหรับชนิดค่า == จะเปรียบเทียบข้อมูล ส่วนชนิดอ้างอิง == มักจะเปรียบเทียบเอกลักษณ์ (เป็นออบเจ็กต์เดียวกันหรือไม่) เว้นแต่จะมีการเขียนทับพฤติกรรมนี้

using System;

class Program
{
    static void Main()
    {
        int a = 5, b = 5;
        Console.WriteLine("ints: " + (a == b));   // True - same value

        object o1 = new object();
        object o2 = new object();
        Console.WriteLine("objects: " + (o1 == o2));   // False - different identity
    }
}

ค่าเริ่มต้น

ชนิดค่าจะมีค่าเริ่มต้นลักษณะเดียวกับศูนย์ (0, false) ส่วนชนิดอ้างอิงจะมีค่าเริ่มต้นเป็น null

using System;

class Program
{
    static void Main()
    {
        int defaultInt = default;
        bool defaultBool = default;
        string defaultString = default;
        Console.WriteLine(defaultInt + ", " + defaultBool + ", null? " + (defaultString == null));
    }
}

สรุปรวม

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

using System;

struct Money { public decimal Amount; }
class Wallet { public decimal Amount; }

class Program
{
    static void Main()
    {
        Money m1 = new Money { Amount = 10 };
        Money m2 = m1; m2.Amount = 99;

        Wallet w1 = new Wallet { Amount = 10 };
        Wallet w2 = w1; w2.Amount = 99;

        Console.WriteLine("Money copy: " + m1.Amount + " (independent)");
        Console.WriteLine("Wallet ref: " + w1.Amount + " (shared)");
    }
}

ตรวจสอบความเข้าใจ

ทดสอบความเข้าใจของคุณเกี่ยวกับชนิดค่าและชนิดอ้างอิง

ทบทวน

ชนิดค่า (int, double, bool, โครงสร้าง) จัดเก็บข้อมูลโดยตรงและถูกคัดลอกเมื่อกำหนดค่า ส่วน ชนิดอ้างอิง (คลาส สตริง อาร์เรย์) จะจัดเก็บการอ้างอิงไปยังออบเจ็กต์บนฮีปและคัดลอกการอ้างอิง เฉพาะชนิดอ้างอิงเท่านั้นที่รองรับค่าว่างโดยค่าเริ่มต้น และพฤติกรรมการกำหนดค่ากับการเปรียบเทียบความเท่ากันก็แตกต่างกันระหว่างชนิดทั้งสองกลุ่ม

using System;

struct V { public int N; }
class R { public int N; }

class Program
{
    static void Main()
    {
        V v1 = new V { N = 1 }; V v2 = v1; v2.N = 9;
        R r1 = new R { N = 1 }; R r2 = r1; r2.N = 9;
        Console.WriteLine(v1.N + " vs " + r1.N);
    }
}

คำถามที่พบบ่อย

บทเรียน “ชนิดค่าเทียบกับชนิดอ้างอิง” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “ชนิดค่าเทียบกับชนิดอ้างอิง” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C# Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C# Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “ชนิดค่าเทียบกับชนิดอ้างอิง”

ดูวิธีจัดเก็บและคัดลอกของแต่ละชนิด คุณปฏิบัติ C# Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C# Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน C# Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน

บทเรียน “ชนิดค่าเทียบกับชนิดอ้างอิง” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน C# Academy นี้ได้ไหม

ได้ บทเรียน C# Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. ชนิดค่าเทียบกับชนิดอ้างอิง
  2. การบรรจุและการนำออกจากกล่อง
  3. การแปลงโดยนัยและโดยชัดแจ้ง
  4. คลาส Convert และการแยกวิเคราะห์
← กลับไปที่ C# Academy