Preprocessor Directives (Chỉ thị tiền xử lý) được xử lý trước khi compile, cho phép include/exclude code dựa trên symbol (conditional compilation symbols). Bắt đầu bằng #, không kết thúc bằng ;.
Các chỉ thị điều kiện
| Chỉ thị | Mục đích |
|---|---|
#define SYMBOL | Định nghĩa symbol (trước mọi code khác) |
#undef SYMBOL | Hủy định nghĩa symbol |
#if SYMBOL | Bắt đầu block điều kiện (true nếu symbol defined) |
#elif SYMBOL | Else-if cho #if |
#else | Else cho #if |
#endif | Kết thúc block #if |
Toán tử trong #if
==,!=(so sánh defined/undefined)&&(AND),||(OR)!(NOT)- Ngoặc
()cho độ ưu tiên
Ví dụ hoàn chỉnh
// Định nghĩa symbol ở đầu file (hoặc Project Properties → Build → Conditional compilation symbols)
#define DEBUG
#define VC_V10
using System;
public class Demo
{
public static void Main()
{
#if (DEBUG && !VC_V10)
Console.WriteLine("DEBUG is defined");
#elif (!DEBUG && VC_V10)
Console.WriteLine("VC_V10 is defined");
#elif (DEBUG && VC_V10)
Console.WriteLine("DEBUG and VC_V10 are defined");
#else
Console.WriteLine("DEBUG and VC_V10 are not defined");
#endif
Console.ReadKey();
}
}
Kết quả
DEBUG and VC_V10 are defined
Cách định nghĩa Symbol (Khuyên dùng: Project Settings)
Thay vì #define trong code, hãy dùng Project Properties → Build → Conditional compilation symbols:
- Debug:
DEBUG;TRACE - Release:
TRACE - Custom:
MYFEATURE;LOGGING;TESTING
Ví dụ thực tế: Logging có điều kiện
using System;
using System.Diagnostics;
public class Logger
{
[Conditional("DEBUG")] // Chỉ compile vào bản DEBUG
public static void Log(string message)
{
Console.WriteLine($"[LOG] {DateTime.Now}: {message}");
}
[Conditional("TRACE")]
public static void Trace(string message)
{
Console.WriteLine($"[TRACE] {message}");
}
}
class Program
{
static void Main()
{
Logger.Log("Starting app..."); // Chỉ chạy nếu DEBUG defined
Logger.Trace("Entering Main"); // Chỉ chạy nếu TRACE defined
Console.WriteLine("App running");
}
}
Các chỉ thị tiền xử lý khác
| Chỉ thị | Mục đích |
|---|---|
#warning "msg" | Cảnh báo compile-time (không dừng build) |
#error "msg" | Lỗi compile-time (dừng build) |
#region / #endregion | Gom nhóm code (IDE fold) |
#line | Thay đổi line number/file name cho compiler |
#pragma warning | Bật/tắt warning cụ thể |
#nullable | Bật/tắt nullable context (C# 8+) |
Best Practices
- Dùng
ConditionalAttributecho method logging/debug thay vì #if lồng nhau. - Giữ logic #if đơn giản, tránh lồng sâu.
- Symbol naming: UPPER_CASE (DEBUG, TRACE, MY_FEATURE).
- Không dùng #if để comment code lớn (dùng // hoặc /* */ hoặc #region).
- Document các custom symbol trong README/CONTRIBUTING.