ภาพรวม
ใน C# อาร์เรย์เป็น Reference Type เมื่อส่งอาร์เรย์เข้าเมธอด จะส่ง Reference (อ้างอิง) ของอาร์เรย์ ไม่ใช่การ Copy ทั้งอาร์เรย์ หมายความว่าเมธอดสามารถ แก้ไขเนื้อหาของอาร์เรย์ต้นฉบับได้
ตัวอย่างโปรแกรม: ส่งอาร์เรย์เพื่อคำนวณค่าเฉลี่ย
using System;
namespace ArrayApplication
{
class MyArray
{
// เมธอดรับอาร์เรย์และขนาด คืนค่าเฉลี่ย
double GetAverage(int[] arr, int size)
{
int sum = 0;
for (int i = 0; i < size; i++)
sum += arr[i];
return (double)sum / size;
}
static void Main(string[] args)
{
MyArray app = new MyArray();
// อาร์เรย์ 5 องค์ประกอบ
int[] balance = new int[] { 1000, 2, 3, 17, 50 };
// ส่งอาร์เรย์เข้าเมธอด (ส่ง Reference)
double avg = app.GetAverage(balance, 5);
Console.WriteLine("ค่าเฉลี่ยคือ: {0}", avg);
Console.ReadKey();
}
}
}ผลลัพธ์
ค่าเฉลี่ยคือ: 214.4
คำอธิบายการทำงาน
1. การส่งอาร์เรย์
double avg = app.GetAverage(balance, 5);
ตัวแปร balance เก็บ Reference (Address) ของอาร์เรย์ใน Heap เมธอด GetAverage ได้รับ Reference เดียวกัน → เข้าถึงข้อมูลเดียวกัน
2. เมธอด GetAverage
double GetAverage(int[] arr, int size)
{
int sum = 0;
for (int i = 0; i < size; i++)
sum += arr[i]; // อ่านค่าจากอาร์เรย์เดียวกัน
return (double)sum / size;
}สำคัญ: การแก้ไขอาร์เรย์ในเมธอด ส่งผลต่อต้นฉบับ
void ModifyArray(int[] arr)
{
arr[0] = 999; // เปลี่ยนค่าองค์ประกอบแรก
}
int[] numbers = { 1, 2, 3 };
ModifyArray(numbers);
Console.WriteLine(numbers[0]); // 999 - ค่าเปลี่ยนไป!การป้องกันการแก้ไข (ถ้าต้องการ)
1. ส่งสำเนา (Clone)
double avg = app.GetAverage((int[])balance.Clone(), 5);
2. ใช้ ReadOnlyCollection / IReadOnlyList
double GetAverage(IReadOnlyListarr) { // ไม่สามารถ arr[0] = 999 ได้ (Compile Error) int sum = 0; for (int i = 0; i < arr.Count; i++) sum += arr[i]; return (double)sum / arr.Count; } // เรียกใช้ double avg = app.GetAverage(balance); // Implicit conversion to IReadOnlyList
3. ใช้ params (สำหรับส่งหลายค่า)
double GetAverage(params int[] numbers)
{
return numbers.Average(); // LINQ
}
// เรียกใช้
double avg = GetAverage(1000, 2, 3, 17, 50);ข้อสังเกตสำคัญ
- อาร์เรย์เป็น Reference Type - ส่ง Reference (Pointer) ไม่ใช่ Copy Object
- เมธอดสามารถแก้ไขเนื้อหาอาร์เรย์ได้ (Mutate) แต่ ไม่สามารถเปลี่ยน Reference ของตัวแปรต้นฉบับได้ (ไม่สามารถทำให้
balanceชี้ไปอาร์เรย์ใหม่ได้) - หากต้องการให้เมธอดสร้างอาร์เรย์ใหม่คืนกลับ ใช้
outหรือrefหรือ Return Array ใหม่ paramsKeyword ทำให้ส่งจำนวนอาร์กิวเมนต์ได้หลากหลาย (Internally เป็น Array)- ใน .NET Core / .NET 5+ แนะนำใช้
Span<T>หรือReadOnlySpan<T>แทน Array สำหรับ Performance และ Safety