ชนิดค่าเทียบกับชนิดอ้างอิง
ดูวิธีจัดเก็บและคัดลอกของแต่ละชนิด
ชนิดค่าเทียบกับชนิดอ้างอิง เป็นบทเรียน 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- ชนิดค่าเทียบกับชนิดอ้างอิง
- การบรรจุและการนำออกจากกล่อง
- การแปลงโดยนัยและโดยชัดแจ้ง
- คลาส Convert และการแยกวิเคราะห์