การบรรจุและการนำออกจากกล่อง
ทำความเข้าใจต้นทุนของการแปลงเป็น object
การบรรจุและการนำออกจากกล่อง เป็นบทเรียน C# Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C# Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C# Academy มีบทเรียนทั้งหมด 4 บทเรียน
การบรรจุค่าคืออะไร
การบรรจุค่าคือการห่อชนิดค่าไว้ภายในออบเจ็กต์ เพื่อให้สามารถใช้งานเสมือนเป็นชนิดอ้างอิงได้ object o = 5; จะบรรจุ int ไว้บนฮีป
using System;
class Program
{
static void Main()
{
int n = 5;
object o = n; // boxing
Console.WriteLine("Boxed value: " + o);
}
}เหตุผลที่เกิดการบรรจุค่า
การบรรจุค่าจะเกิดขึ้นเมื่อชนิดค่าถูกกำหนดให้กับตัวแปรชนิด object (หรืออินเทอร์เฟซ) สภาพแวดล้อมขณะทำงานจะจัดสรรกล่องบนฮีปที่เก็บสำเนาของค่าไว้
using System;
class Program
{
static void Main()
{
double d = 3.14;
object boxed = d; // boxing copies d into a heap object
Console.WriteLine(boxed);
}
}การนำค่าออกจากกล่องคืออะไร
การนำค่าออกจากกล่องคือการดึงชนิดค่ากลับออกจากกล่องด้วยการแปลงชนิดอย่างชัดเจน ชนิดที่ใช้แปลงต้องตรงกับชนิดที่ถูกบรรจุไว้อย่างแน่นอน
using System;
class Program
{
static void Main()
{
object o = 42; // boxing
int n = (int)o; // unboxing
Console.WriteLine("Unboxed: " + n);
}
}การนำค่าออกจากกล่องต้องใช้ชนิดที่ถูกต้อง
คุณต้องนำค่าออกจากกล่องให้เป็นชนิดเดิมที่แน่นอน การนำค่าออกมาเป็นชนิดอื่นจะทำให้เกิด InvalidCastException
using System;
class Program
{
static void Main()
{
object o = 100;
try
{
long wrong = (long)o; // InvalidCastException at runtime
Console.WriteLine(wrong);
}
catch (InvalidCastException)
{
Console.WriteLine("Must unbox to int, not long");
}
}
}การบรรจุค่าจะสร้างสำเนา
การบรรจุค่าจะคัดลอกค่า ดังนั้นการเปลี่ยนแปลงค่าต้นฉบับภายหลังจะไม่เปลี่ยนสำเนาที่อยู่ในกล่อง
using System;
class Program
{
static void Main()
{
int n = 1;
object o = n; // box copies 1
n = 99;
Console.WriteLine("original=" + n + ", boxed=" + o);
}
}ต้นทุนของการบรรจุค่า
ทุกกล่องจะจัดสรรหน่วยความจำบนฮีปและเพิ่มภาระให้การเก็บคืนหน่วยความจำ ในลูปที่ทำงานบ่อย ค่าใช้จ่ายส่วนนี้อาจลดประสิทธิภาพลงอย่างเห็นได้ชัด
using System;
class Program
{
static void Main()
{
// Each iteration boxes an int -> many heap allocations
object sumBox = 0;
for (int i = 0; i < 5; i++)
{
int current = (int)sumBox + i;
sumBox = current; // box again
}
Console.WriteLine("Result: " + sumBox);
}
}หลีกเลี่ยงการบรรจุค่าด้วยชนิดทั่วไป
คอลเลกชันแบบทั่วไป เช่น List<int> จะจัดเก็บชนิดค่าโดยไม่ต้องบรรจุค่า ต่างจาก ArrayList แบบไม่ใช้ชนิดทั่วไปในรุ่นเก่า
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
var list = new List<int>(); // no boxing
list.Add(1);
list.Add(2);
int first = list[0]; // no unboxing
Console.WriteLine("First: " + first);
}
}การบรรจุค่ากับอินเทอร์เฟซ
การกำหนดโครงสร้างให้กับตัวแปรอินเทอร์เฟซก็จะบรรจุโครงสร้างนั้นเช่นกัน เพราะการอ้างอิงของอินเทอร์เฟซต้องชี้ไปยังออบเจ็กต์บนฮีป
using System;
class Program
{
static void Main()
{
int n = 7;
IComparable c = n; // boxing to interface
Console.WriteLine(c.CompareTo(10));
}
}การตรวจจับชนิดที่ถูกบรรจุค่า
คุณสามารถตรวจสอบชนิดของออบเจ็กต์ขณะทำงานด้วย is ก่อนนำค่าออกจากกล่องอย่างปลอดภัย
using System;
class Program
{
static void Main()
{
object o = 3.5;
if (o is double d)
Console.WriteLine("It is a double: " + d);
else
Console.WriteLine("Not a double");
}
}การบรรจุค่าในการต่อสตริง
การนำชนิดค่าไปต่อกับสตริงอาจทำให้เกิดการบรรจุค่า การใช้การแทรกค่าหรือ ToString มักอ่านเข้าใจได้ชัดเจนกว่า แม้โดยทั่วไปการบรรจุค่าในกรณีนี้จะมีผลกระทบเพียงเล็กน้อย
using System;
class Program
{
static void Main()
{
int count = 3;
string msg = "Count is " + count; // count is converted
Console.WriteLine(msg);
}
}สรุปรวม
การบรรจุค่าเชื่อมโลกของชนิดค่ากับชนิดอ้างอิงเข้าด้วยกัน แต่มีต้นทุนจากการจัดสรรหน่วยความจำ ควรใช้ชนิดทั่วไปเพื่อหลีกเลี่ยงการบรรจุค่า และนำค่าออกจากกล่องโดยใช้ชนิดที่ตรงกันพร้อมตรวจสอบอย่างปลอดภัย
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
object boxed = 256;
if (boxed is int value)
Console.WriteLine("Safely unboxed: " + value);
var noBox = new List<int> { 1, 2, 3 };
Console.WriteLine("Generic count: " + noBox.Count);
}
}ตรวจสอบความเข้าใจ
ทดสอบความเข้าใจของคุณเกี่ยวกับการบรรจุค่าและการนำค่าออกจากกล่อง
ทบทวน
การบรรจุค่าจะห่อชนิดค่าไว้ในออบเจ็กต์บนฮีป (เช่น object o = 5;) ส่วน การนำค่าออกจากกล่องจะดึงค่าออกมาด้วยการแปลงชนิดอย่างชัดเจนให้เป็นชนิดเดิมที่แน่นอน การบรรจุค่าจะคัดลอกค่าและจัดสรรหน่วยความจำ จึงเพิ่มภาระให้การเก็บคืนหน่วยความจำ ควรใช้คอลเลกชันแบบทั่วไป เช่น List<int> เพื่อหลีกเลี่ยงการบรรจุค่า และใช้ is เพื่อนำค่าออกจากกล่องอย่างปลอดภัย
using System;
class Program
{
static void Main()
{
object boxed = 42; // box
int n = (int)boxed; // unbox
Console.WriteLine(n);
}
}คำถามที่พบบ่อย
บทเรียน “การบรรจุและการนำออกจากกล่อง” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การบรรจุและการนำออกจากกล่อง” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C# Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C# Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การบรรจุและการนำออกจากกล่อง”
ทำความเข้าใจต้นทุนของการแปลงเป็น object คุณปฏิบัติ C# Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C# Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน C# Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน
บทเรียน “การบรรจุและการนำออกจากกล่อง” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน C# Academy นี้ได้ไหม
ได้ บทเรียน C# Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- ชนิดค่าเทียบกับชนิดอ้างอิง
- การบรรจุและการนำออกจากกล่อง
- การแปลงโดยนัยและโดยชัดแจ้ง
- คลาส Convert และการแยกวิเคราะห์