当前位置: 首页 > news >正文

C#学习12——预处理

一、预处理指令:

解释:是在编译前由预处理器执行的命令,用于控制编译过程。这些命令以 # 开头,每行只能有一个预处理指令,且不能包含在方法或类中。

个人理解:就是游戏里面的备战阶段(不同对局,不同选英雄。。。)

1.#define 定义字符和 #undef取消定义字符
#define TEST
#undef TEST  // 取消定义(删掉则输出"TEST 已定义")#if TESTConsole.WriteLine("TEST 已定义");
#elseConsole.WriteLine("TEST 未定义");  // 输出此行"TEST 未定义"
#endif

#define 宏常量与内置的 const 常量区别:
特性            #define 宏常量                                    const 常量
定义方式    定义条件符号,在编译前替换文本       语言关键字,声明为不可修改的变量
作用域       无作用域限制                                        遵循变量作用域(块、类作用域等)
类型安全    无类型检查,可能导致意外行为          有类型声明,编译器会进行类型检查
内存占用    无独立内存,直接替换为文本              可能占用内存(取决于编译器优化)
调试支持    调试时不可见(已替换为文本)          调试时可见(有独立符号)
灵活性       可定义复杂表达式或代码片段               仅能定义简单值

2.条件编译指令#if#else#elif#endif
#define DEBUG  // 定义一个符号(通常在项目属性中设置)#if !DEBUGConsole.WriteLine("不是DEBUG模式");//输出这一行
#elif DEBUGConsole.WriteLine("DEBUG模式");
#elseConsole.WriteLine("其他模式");
#endif

配套使用规则

这些指令必须成对出现,形成一个完整的条件编译块:

  • #if:开始条件编译块,检查符号是否定义。
  • #elif(可选):提供额外的条件分支。
  • #else(可选):定义默认分支(当所有条件都不满足时)。
  • #endif:结束条件编译块。
3.#error错误和警告指令(可嵌套)
#if OLD_VERSION#error 此代码需要更新到新版本
#elseConsole.WriteLine("代码正常运行");
#endif
4.#warning    生成编译器警告信息
#warning 此方法已过时,需要重构
5.#region:标记一个可折叠代码块的开始。#endregion:标记一个可折叠代码块的结束。
#region PropertiesConsole.WriteLine("这一段是代码块1");Console.WriteLine("这一段是代码块1");Console.WriteLine("这一段是代码块1");
#endregion#region MethodsConsole.WriteLine("这一段是代码块2");Console.WriteLine("这一段是代码块2");Console.WriteLine("这一段是代码块2");
#endregion
6.#line显式指定编译器在生成错误或警告时报告的行号和文件名

#line 数字 "文件名"

#line default恢复编译器使用实际的行号和文件名。

#line hidden隐藏代码行(通常用于编译器内部实现,如生成的状态机代码)。

#line 10 "Template.tt"public void GeneratedMethod() {Console.WriteLine("Hello from generated code!");}
#line default
7.#pragma    用于给编译器发送特殊指令,例如禁用或恢复特定的警告。
#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    控制可空性上下文和注释,允许启用或禁用对可空引用类型的编译器检查。

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 折叠代码块,提升可读性。)

5) 灵活调试(#warning 和 #error 在编译时生成提示或错误)

相关文章:

  • 【PmHub面试篇】Gateway全局过滤器统计接口调用耗时面试要点解析
  • # 将本地UI生成器从VLLM迁移到DeepSeek API的完整指南
  • 【深入 LangChain 的 Model I/O】提示设计、模型调用与输出解析全解析
  • 多数据库学习之星瑞格[SinoDB]数据库安装部署指南
  • 历史记录隐藏的安全风险
  • Windows清理之后,资源管理器卡顿-解决方法
  • Prj10--8088单板机C语言8259测试(1)
  • 服务器被攻击了怎么办
  • Java-IO流之字节输入流详解
  • AJ-Report
  • android NDK 的 -> 是什么意思
  • 【开源工具】Python+PyQt5打造智能桌面单词记忆工具:悬浮窗+热键切换+自定义词库
  • 使用 Golang `testing/quick` 包进行高效随机测试的实战指南
  • GitHub 趋势日报 (2025年06月02日)
  • Splitting Items
  • Ubuntu22.04 安装 Miniconda3
  • WINUI——Magewell视频捕捉开发手记
  • 【数据库】安全性
  • 深入解析 Java 中的 synchronized:从使用到底层原理的全面详解
  • 基于Matlab实现LDA算法
  • wordpress网站变灰/世界网站排名查询
  • c 动态网站开发/免费推广网
  • 深圳做网站乐云seo费用优惠/百度推广个人怎么开户
  • 天津做网站的网络公司/关键词林俊杰mp3在线听
  • 济南市建设工程招标投标协会网站/搜索图片识别
  • 三拼域名做网站长不长/seo整站优化外包公司