คำจำกัดความ
- Lvalue (Locator Value) - นิพจน์ที่อ้างอิงถึงตำแหน่งหน่วยความจำ (Memory Location) สามารถอยู่ด้านซ้ายหรือขวาของ Assignment ได้
- Rvalue (Read Value) - นิพจน์ที่มีแค่ค่า ไม่มีตำแหน่งหน่วยความจำ ควรอยู่ด้านขวาของ Assignment เท่านั้น
ตัวอย่าง Lvalue
int a = 10; // a เป็น Lvalue (ตัวแปร)
a = 20; // a อยู่ด้านซ้าย - OK
int b = a; // a อยู่ด้านขวา - OK (อ่านค่า)
a = b; // a อยู่ด้านซ้าย, b อยู่ขวา - OK
ตัวอย่าง Rvalue
int a = 100; // 100 เป็น Rvalue (Literal)
100 = a; // ❌ Compile Error! 100 ไม่มี Memory Address
a + b = 10; // ❌ Compile Error! a+b เป็น Rvalue (ผลลัพธ์ชั่วคราว)
ประเภทของ Lvalues และ Rvalues
| นิพจน์ | ประเภท | คำอธิบาย |
|---|---|---|
ตัวแปร (int x) |
Lvalue | มี Memory Address |
Property (obj.Prop) |
Lvalue* | ถ้ามี Setter (*Indexer ก็รวม) |
Array Element (arr[0]) |
Lvalue | มี Memory Address |
Literal (100, "hello", true) |
Rvalue | ค่าคงที่ ไม่มี Address |
Expression (a + b) |
Rvalue | ผลลัพธ์ชั่วคราว |
Method Return (GetValue()) |
Rvalue | คืนค่า ไม่ใช่ Reference (ปกติ) |
| ref/out Parameter | Lvalue | ส่ง Reference จริง |
C# 7.0+ : Ref Returns และ Ref Locals (Advanced)
C# สมัยใหม่รองรับการคืนค่า Reference ทำให้ Method Return กลายเป็น Lvalue ได้:
// Ref Return - คืน Reference แทนค่า
public ref int FindNumber(int[] numbers, int target) {
for (int i = 0; i < numbers.Length; i++) {
if (numbers[i] == target) {
return ref numbers[i]; // คืน Reference ของ Array Element
}
}
throw new Exception("Not found");
}
// ใช้งาน - กลายเป็น Lvalue ได้!
int[] arr = { 1, 2, 3, 4, 5 };
ref int found = ref FindNumber(arr, 3);
found = 999; // แก้ไขค่าใน Array จริง!
Console.WriteLine(arr[2]); // 999
สรุปง่ายๆ
- Lvalue = "กล่อง" ที่เก็บค่าได้ → วางซ้าย
=ได้ - Rvalue = "ค่า" เอง → วางขวา
=เท่านั้น - Variable = Lvalue | Literal = Rvalue | Expression = Rvalue