Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C#

Directives #if DEBUG vs #else #endif ใน C#

Preprocessor Directives สำหรับ Debug/Release Build ใน C#

C# ใช้ Preprocessor Directives (ขึ้นต้นด้วย #) เพื่อควบคุมการคอมไพล์โค้ดตาม Build Configuration (Debug/Release)

Build Configuration ใน Visual Studio

  • Debug - ใช้สำหรับ Debugging มี Symbol (PDB), ไม่ Optimize, Define DEBUG และ TRACE
  • Release - Build สำหรับ Production Optimize โค้ด, Define TRACE เท่านั้น

เปลี่ยน Configuration: Toolbar → Dropdown (Debug/Release) หรือ Build → Configuration Manager

Syntax พื้นฐาน

#if DEBUG
    // โค้ดนี้คอมไพล์เฉพาะ Debug build
    Console.WriteLine("Debug mode");
#else
    // โค้ดนี้คอมไพล์เฉพาะ Release build (และไม่ใช่ DEBUG)
    Console.WriteLine("Release mode");
#endif

Directives ที่เกี่ยวข้อง

Directiveคำอธิบาย
#if SYMBOLคอมไพล์ถ้า SYMBOL ถูก Define
#elif SYMBOLElse-if สำหรับ #if
#elseกรณี #if เป็น false
#endifปิด #if (บังคับ)
#define SYMBOLDefine Symbol (ต้องอยู่บนสุดไฟล์)
#undef SYMBOLUndefine Symbol
#warning "msg"แสดง Warning ตอน Build
#error "msg"แสดง Error หยุด Build

ตัวอย่างการใช้งาน

1. Basic Debug/Release

using System;

class Program
{
    static void Main()
    {
        #if DEBUG
            Console.WriteLine("Mode = Debug");
            Console.WriteLine("Connection: Server=dev-db;Database=MyApp;");
        #else
            Console.WriteLine("Mode = Release");
            Console.WriteLine("Connection: Server=prod-db;Database=MyApp;");
        #endif
        
        Console.ReadLine();
    }
}

Output (Debug): Mode = Debug | Output (Release): Mode = Release

2. Logging/Diagnostics เฉพาะ Debug

public class OrderService
{
    private readonly ILogger _logger;
    
    public void ProcessOrder(Order order)
    {
        #if DEBUG
        _logger.LogDebug("Processing order {OrderId} with items: {@Items}", 
            order.Id, order.Items);
        #endif
        
        // Business logic...
        
        #if DEBUG
        _logger.LogDebug("Order {OrderId} completed", order.Id);
        #endif
    }
}

3. Custom Symbol (Define เอง)

// ใน .csproj หรือ Project Properties → Build → Conditional compilation symbols
// DEBUG;TRACE;MY_FEATURE

public class FeatureService
{
    public void DoWork()
    {
        #if MY_FEATURE
        Console.WriteLine("Feature Enabled!");
        #else
        Console.WriteLine("Feature Disabled");
        #endif
    }
}

4. ConditionalAttribute (ทางเลือกที่ดีกว่าสำหรับ Method)

using System.Diagnostics;

public class Logger
{
    // Method นี้จะถูก Remove ออกจาก IL ถ้าไม่ได้ Define DEBUG
    // เรียกได้แต่ใน Debug build
    [Conditional("DEBUG")]
    public void LogDebug(string message)
    {
        Console.WriteLine($"[DEBUG] {message}");
    }
    
    [Conditional("TRACE")]
    public void LogTrace(string message)
    {
        Console.WriteLine($"[TRACE] {message}");
    }
}

ข้อดีของ ConditionalAttribute:

  • โค้ดเรียก Method ยังคงอยู่ แต่ Method body ถูกลบออก (No IL)
  • ไม่ต้อง wrapping #if ทุกครั้งที่เรียก
  • Argument evaluation ก็ถูก skip ด้วย (ประหยัด performance)

Predefined Symbols

Symbolความหมาย
DEBUGDebug build (Define โดย Default)
TRACEDebug และ Release (Define โดย Default)
NETFRAMEWORKTarget .NET Framework
NETCOREAPPTarget .NET Core
NETSTANDARDTarget .NET Standard
NET6_0, NET7_0, NET8_0Target Framework Version เฉพาะ

Multi-targeting Example

public class PlatformService
{
    public string GetPlatformInfo()
    {
        #if NETFRAMEWORK
        return ".NET Framework";
        #elif NETCOREAPP
        return ".NET Core / .NET 5+";
        #elif NETSTANDARD
        return ".NET Standard";
        #else
        return "Unknown";
        #endif
    }
}

Best Practices

DoDon't
ใช้ #if DEBUG สำหรับ Logging/Diagnosticsใช้ #if เยอะจนโค้ดอ่านยาก
ใช้ [Conditional("DEBUG")] สำหรับ MethodWrap Logic ทั้ง Method ด้วย #if
Define Custom Symbol ใน .csprojDefine Symbol ในไฟล์โค้ด (#define)
Comment ให้ชัดเจน ว่าทำไมถึง #ifทิ้ง #if ไว้โดยไม่มีคำอธิบาย

สรุป

  • #if DEBUG ... #else ... #endif ควบคุมการคอมไพล์ตาม Build Config
  • DEBUG Define ใน Debug build, TRACE Define ในทั้งคู่
  • ใช้ [Conditional("DEBUG")] สำหรับ Method Logging - สะดวกกว่า
  • Custom Symbol 定義在 .csproj (<DefineConstants>)
  • Release build: โค้ดใน #if DEBUG ถูกลบออกจาก Assembly เลย (Zero overhead)