ภาพรวม
คำสั่งประมวลผล (Preprocessor Directive) #line ใน C# ใช้สำหรับ เปลี่ยนหมายเลขบรรทัดและชื่อไฟล์ ที่คอมไพลอร์รายงานในข้อความผิดพลาด (Error) และคำเตือน (Warning) มีประโยชน์เมื่อโค้ดถูกสร้างอัตโนมัติ (Code Generation) หรือผ่านเครื่องมือ Preprocessor
ไวยากรณ์
#line number ["filename"] #line default #line hidden
ตัวเลือก
#line number- ตั้งหมายเลขบรรทัดถัดไปเป็น number#line number "filename"- ตั้งหมายเลขบรรทัดและชื่อไฟล์#line default- คืนค่าการนับบรรทัดปกติ#line hidden- ซ่อนบรรทัดจาก Debugger (Step over)
ตัวอย่างที่ 1: เปลี่ยนหมายเลขบรรทัดและชื่อไฟล์
#line 100 "demo" int a; // CS0168 บรรทัด 100 int b; // CS0168 บรรทัด 101 int c; // CS0168 บรรทัด 102
คอมไพลอร์จะรายงาน Warning CS0168 (ตัวแปรไม่ได้ใช้) ที่บรรทัด 100, 101, 102 ในไฟล์ "demo" แทนที่จะเป็นบรรทัดจริงในไฟล์ต้นฉบับ
ตัวอย่างที่ 2: คืนค่า Default Line Numbering
#line default char a; // CS0168 บรรทัด 15 (กลับมานับปกติ) float b; // CS0168 บรรทัด 16
#line default จะคืนการนับบรรทัดกลับสู่ปกติ นับจากบรรทัดจริงในไฟล์
ตัวอย่างที่ 3: ซ่อนโค้ดจาก Debugger
using System;
public class Demo
{
public static void Main()
{
Console.WriteLine("เริ่มต้น");
#line hidden
// โค้ดนี้จะถูก Step Over โดย Debugger
DoInternalWork();
#line default
Console.WriteLine("เสร็จสิ้น");
}
static void DoInternalWork()
{
// รายละเอียดภายในที่ไม่อยากให้ Debugger เข้าไป
System.Threading.Thread.Sleep(100);
}
}กรณีการใช้งานจริง (Real-world Use Cases)
1. Code Generators (Source Generators, T4 Templates)
เมื่อโค้ดถูกสร้างจาก Template ใช้ #line เพื่อให้ Error ชี้ไปที่ Template ต้นฉบับ ไม่ใช่ไฟล์ที่ Generate ออกมา
2. ASP.NET Razor / Blazor
Razor Engine ใช้ #line เพื่อ Map โค้ด C# ที่ Generate กลับไปยังไฟล์ .cshtml/.razor ต้นฉบับ
3. Aspect-Oriented Programming (AOP) / IL Weaving
Tools เช่น Fody, PostSharp ใช้ #line รักษาข้อมูล Debugging
4. Domain-Specific Languages (DSL) Parsers
Parser ที่แปลง DSL เป็น C# ใช้ #line ชี้กลับไปที่ไฟล์ DSL
ข้อสังเกตสำคัญ
#lineส่งผลต่อ Compile-time errors/warnings และ Debugger (PDB)- ไม่ส่งผลต่อ Runtime behavior (Stack Trace ใช้ข้อมูลจาก PDB)
- Visual Studio รองรับ #line hidden สำหรับ Step Over โค้ด Generated
- ใช้จริงน้อยในโค้ดมือเขียน มากใน Tooling/Generators