C#学习12——预处理

一、预处理指令:

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

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

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

  1. 灵活调试(#warning#error 在编译时生成提示或错误)
相关推荐
fengye20716142 分钟前
板凳-------Mysql cookbook学习 (十)
学习·mysql·adb
小白杨树树1 小时前
【SSM】SpringBoot学习笔记1:SpringBoot快速入门
spring boot·笔记·学习
万能程序员-传康Kk2 小时前
智能教育个性化学习平台-java
java·开发语言·学习
字节高级特工2 小时前
【Linux篇】0基础之学习操作系统进程
linux·运维·服务器·数据结构·windows·学习·list
hopetomorrow2 小时前
学习路之PHP--webman安装及使用
android·学习·php
待什么青丝2 小时前
【TMS570LC4357】之相关驱动开发学习记录1
c语言·arm开发·驱动开发·学习
Kethy__2 小时前
算法分析与设计-动态规划、贪心算法
c++·学习·算法·贪心算法·动态规划
s_little_monster2 小时前
【Linux】网络--数据链路层--以太网
linux·运维·网络·经验分享·笔记·学习·计算机网络
lil44x_4 小时前
嵌入式学习笔记DAY33(网络编程——TCP)
服务器·笔记·学习