一、预处理指令:
解释:是在编译前由预处理器执行的命令,用于控制编译过程。这些命令以 # 开头,每行只能有一个预处理指令,且不能包含在方法或类中。
个人理解:就是游戏里面的备战阶段(不同对局,不同选英雄。。。)
1.#define 定义字符和 #undef取消定义字符
        
            
            
              cs
              
              
            
          
          #define TEST
#undef TEST  // 取消定义(删掉则输出"TEST 已定义")
#if TEST
    Console.WriteLine("TEST 已定义");
#else
    Console.WriteLine("TEST 未定义");  // 输出此行"TEST 未定义"
#endif
        #define 宏常量与内置的 const 常量区别:
特性 #define 宏常量 const 常量
定义方式 定义条件符号,在编译前替换文本 语言关键字,声明为不可修改的变量
作用域 无作用域限制 遵循变量作用域(块、类作用域等)
类型安全 无类型检查,可能导致意外行为 有类型声明,编译器会进行类型检查
内存占用 无独立内存,直接替换为文本 可能占用内存(取决于编译器优化)
调试支持 调试时不可见(已替换为文本) 调试时可见(有独立符号)
灵活性 可定义复杂表达式或代码片段 仅能定义简单值
2.条件编译指令 #if, #else, #elif, #endif
        
            
            
              cs
              
              
            
          
          #define DEBUG  // 定义一个符号(通常在项目属性中设置)
#if !DEBUG
    Console.WriteLine("不是DEBUG模式");//输出这一行
#elif DEBUG
    Console.WriteLine("DEBUG模式");
#else
    Console.WriteLine("其他模式");
#endif
        配套使用规则
这些指令必须成对出现,形成一个完整的条件编译块:
#if:开始条件编译块,检查符号是否定义。#elif(可选):提供额外的条件分支。#else(可选):定义默认分支(当所有条件都不满足时)。#endif:结束条件编译块。
3.#error错误和警告指令(可嵌套)
        
            
            
              cs
              
              
            
          
          #if OLD_VERSION
        #error 此代码需要更新到新版本
#else
        Console.WriteLine("代码正常运行");
#endif
        4.#warning 生成编译器警告信息
            
            
              cs
              
              
            
          
          #warning 此方法已过时,需要重构
        5.#region :标记一个可折叠代码块的开始。#endregion:标记一个可折叠代码块的结束。
        
            
            
              cs
              
              
            
          
          #region Properties
    Console.WriteLine("这一段是代码块1");
    Console.WriteLine("这一段是代码块1");
    Console.WriteLine("这一段是代码块1");
#endregion
#region Methods
    Console.WriteLine("这一段是代码块2");
    Console.WriteLine("这一段是代码块2");
    Console.WriteLine("这一段是代码块2");
#endregion
        6.#line显式指定编译器在生成错误或警告时报告的行号和文件名
#line 数字 "文件名"
#line default恢复编译器使用实际的行号和文件名。
#line hidden隐藏代码行(通常用于编译器内部实现,如生成的状态机代码)。
            
            
              cs
              
              
            
          
          #line 10 "Template.tt"
    public void GeneratedMethod() {
        Console.WriteLine("Hello from generated code!");
    }
#line default
        7.#pragma 用于给编译器发送特殊指令,例如禁用或恢复特定的警告。
            
            
              cs
              
              
            
          
          #pragma warning disable CS0168  // 禁用"变量未使用"的警告
int unusedVariable;    // 不会触发CS0168警告
#pragma warning restore CS0168  // 恢复警告
int unusedVariable1;    // 会触发CS0168警告
        拓展:
#pragma checksum :校验
#pragma optimize:控制代码优化(如 #pragma optimize "g", 启用尾调用优化)。
#pragma pack:控制结构体的内存对齐(在C/C++中更常见,C#中较少使用)。
8.nullable 控制可空性上下文和注释,允许启用或禁用对可空引用类型的编译器检查。
            
            
              cs
              
              
            
          
          string? nullableString = null; // 不会发出警告,默认启用可空注释
#nullable disable annotations
string? nullableString1 = null;//警告,因为可空注释已禁用
Console.WriteLine(nullableString.Length);//警告,出现空引用
#nullable disable
// 潜在的运行时错误
Console.WriteLine(nullableString1.Length);//不会发出警告,因为可空注释和警告都已禁用
#nullable enable
string anotherString = null; // 警告,空文本
Console.WriteLine(anotherString.Length); // 警告,因为可空注释和警告都启用
        
二、为什么要用预处理命令?
1.为什么要用这个?
1)不同环境编译不同代码(调试发布模式Debug,跨平台代码Windows,Linux,IOS)
2)快速定位:
a.标记暂时跳过的功能。
b.提醒团队成员完成关键代码
3)功能开关
#define NEW_UI
class Program {
static void Main() {
#if NEW_UI
ShowNewUI();
#else
ShowOldUI();
#endif
}
}
以 # 开始,不是语句,不以分号 ; 结束
4)提高可读性(用 #region 和 #endregion 折叠代码块,提升可读性。)
- 灵活调试(
#warning和#error在编译时生成提示或错误)