【C#基础】C# 预处理器指令
序号 | 系列文章 |
---|---|
8 | 【C#基础】C# 面向对象编程 |
9 | 【C# 基础】C# 异常处理操作 |
10 | 【C#基础】C# 正则表达式 |
文章目录
- 前言
- 1,预处理器指令的概念
- 2,预处理器指令的定义与使用
- 2.1,可为空上下文
- 2.2,定义符号
- 2.3,条件编译
- 2.4,定义区域
- 2.5,错误和警告信息
- 2.6,杂注
- 3,预处理器指令的用途
- 结语
前言
😺大家好,我是writer桑,前面一章已经学习了 C# 中正则表达式的使用,那本章就开始学习 C# 程序中的预处理器指令,希望看完大家能够有所收获,感谢支持!
1,预处理器指令的概念
预处理器指令是指编译器在实际编译开始之前对信息进行预处理。通常用于简化源程序在不同的执行环境中的更改和编译。例如可以替换文本中的标记,将其他内容插入源文件,或者通过移除几个部分的文本来取消一部分文件的编译。不同于 C 和 C++ 中的指令,在 C# 中不能使用这些指令来创建宏,而且预处理器指令必须是一行中唯一的代码,不能掺杂其它。
示例如下:
#define condition // 定义 condition 字符
using System;public class ExampleProgram
{static void Main(string[] args){#if (condition) // 测试 condition 是否为真Console.WriteLine("condition is defined");#elseConsole.WriteLine("condition is not defined");#endifConsole.ReadLine(); }
}
2,预处理器指令的定义与使用
在 C# 程序中,所有的预处理器指令都是以标识符 # 开始,例如 #define 和 #if,并且预处理器指令之前只能出现空格不能出现任何代码。另外,预处理器指令不是语句,因此它们不需要以分号;结尾。
2.1,可为空上下文
#nullable 预处理器指令用于设置可为空注释上下文和为空警告上下文。#nullable 指令控制着是否可为空注释是否有效,以及是否给出为 Null 的警告。设置着每个上下文要么处于已禁用状态,要么处于已启用状态 。
下表列出 #nullable 指令的用法:
用法 | 描述 |
---|---|
#nullable disable | 将可为空注释和警告上下文设置为“已禁用”。 |
#nullable enable | 将可为空注释和警告上下文设置为“已启用”。 |
#nullable restore | 将可为空注释和警告上下文还原为项目设置。 |
#nullable disable annotations | 将可为空注释上下文设置为“已禁用”。 |
#nullable enable annotations | 将可为空注释上下文设置为“已启用”。 |
#nullable restore annotations | 将可为空注释上下文还原为项目设置。 |
#nullable disable warnings | 将可为空警告上下文设置为“已禁用”。 |
#nullable enable warnings | 将可为空警告上下文设置为“已启用”。 |
#nullable restore warnings | 将可为空警告上下文还原为项目设置。 |
代码示例:
using System;public class ExampleProgram
{static void Main(string[] args){string? str;#nullable disable // 将可为空注释和警告上下文设置为“已禁用”。 Console.WriteLine(str); // 报错: 使用了未赋值的局部变量“str”#nullable enable // 将可为空注释和警告上下文设置为“已启用”。 Console.WriteLine(str);}
}
代码界面:(PS:笔者使用的代码编辑器是 Visual Studio 2022)
2.2,定义符号
可以使用定义符号 #define 和 取消定义符号 #undef 两个预处理器指令来定义或取消定义条件编译的符号。定义符号可用于 #if 等编译指令的条件,使用 #define 来定义符号,将符号用作传递给 #if 指令的表达式。
代码示例:
#define VERBOSE // 定义符 #define
using System;public class ExampleProgram
{static void Main(string[] args){#if VERBOSEConsole.WriteLine("详细输出版本");#endif}
}
代码执行结果:
详细输出版本
2.3,条件编译
可以使用以下四个预处理器指令来控制条件编译:
- #if:打开条件编译,其中仅在定义了指定的符号时才会编译代码。
- #elif:关闭前面的条件编译,并基于是否定义了指定的符号打开一个新的条件编译。
- #else:关闭前面的条件编译,如果没有定义前面指定的符号,打开一个新的条件编译。
- #endif:关闭前面的条件编译。
代码示例:
#define condition2 // 定义 condition 字符
using System;public class ExampleProgram
{static void Main(string[] args){#if (condition)Console.WriteLine("condition is defined");#elif (condition2) // 测试 condition2 是否为真 Console.WriteLine("condition2 is defined");#elseConsole.WriteLine("condition is not defined");#endifConsole.ReadLine();}
}
代码执行结果:
csharp condition2 is defined
补充:
#if 以及 #else、#elif、#endif、#define 和 #undef 指令,允许在这些指令之间存在一个或多个符号里面包括或排除代码。其中,#if 指令开头的条件指令必须以 #endif 指令显式终止。可以使用#define 指令你定义一个符号,通过将该符号用作传递给 #if 指令的表达式。条件编译指令的用法和 C# 中的条件判断语句 if、elif 和 else 语句差不多。
2.4,定义区域
可以使用定义区域符号 #region 和 #endregion 分别表示启动区域和结束区域。这两个预处理器指令来定义可在大纲中折叠的代码区域。利用 #region 和 #endregion 指令,可以指定在使用代码编辑器的大纲功能时可展开或折叠的代码块。#region 指令后面可跟折叠区域的名称。在较长的代码文件中,折叠或隐藏一个或多个代码区域十分方便。
代码示例:
using System;#region MyClass definition
public class ExampleProgram
{static void Main(string[] args){}
}
#endregion
折叠前:
折叠后:
2.5,错误和警告信息
可以使用错误和警告信息指令告诉编译器生成用户定义的编译器错误和警告,并控制行信息。其中包括 #error、#warning 和 #line 指令。
#error:使用指定的消息生成编译器错误。
示例如下:
using System;public class ExampleProgram
{static void Main(string[] args){// 错误:此方法中的弃用代码。#error Deprecated code in this method. Console.WriteLine("This is Deprecated code");}
}
代码界面:
#warning:使用指定的消息生成编译器警告。
示例如下:
using System;public class ExampleProgram
{static void Main(string[] args){// 警告:此方法中的弃用代码。#warning Deprecated code in this method.Console.WriteLine("This is Deprecated code");}
}
代码界面:
#line:更改用编译器消息输出的行号。
示例如下:
using System;public class ExampleProgram
{static void Main(){
#line 200 "Special"int i;int j;
#line default char c;float f;
#line hidden // 编号不受影响string s;double d;}
}
编译产生以下输出:
Special(200,13): warning CS0168: The variable ‘i’ is declared but never used
Special(201,13): warning CS0168: The variable ‘j’ is declared but never used
MainClass.cs(9,14): warning CS0168: The variable ‘c’ is declared but never used
MainClass.cs(10,15): warning CS0168: The variable ‘f’ is declared but never used
MainClass.cs(12,16): warning CS0168: The variable ‘s’ is declared but never used
MainClass.cs(13,16): warning CS0168: The variable ‘d’ is declared but never used
- #line 200 指令将下一行的行号强制设为 200(尽管默认值为 #6);在执行下一个 #line 指令前,文件名都会报告为“特殊”。
- #line default 指令将行号恢复至默认行号,这会对上一指令重新编号的行进行计数。
- #line hidden 指令能对调试程序隐藏连续行,当开发者逐行执行代码时,介于 #line hidden 和下一 #line 指令(假设它不是其他 #line hidden 指令)间的任何行都将被跳过。
2.6,杂注
#pragma 为编译器给出特殊指令以编译它所在的文件,这些指令必须受编译器支持。换句话说,不能使用 #pragma 创建自定义的预处理指令。
#pragma 指令的语法可定义为: #pragma <pragma-name> <pragma-arguments>,其中 pragma-name 为编译器支持 pragma 的名称,pragma-arguments 是特定于 pragma 的参数。 例如 #pragma warning 表示启用或禁用警告,#pragma checksum 表示生成校验和。
代码示例:
using System;#pragma warning disable 414, CS3021
[CLSCompliant(false)]
public class C
{int i = 1;static void Main(){}
}#pragma warning restore CS3021
[CLSCompliant(false)]
public class D
{int i = 1;public static void F(){}
}
代码界面:
3,预处理器指令的用途
预处理器指令的用途总结为以下几点:
- 有利于项目的调式和运行。例如说可以使用条件编译指令控制程序流的执行,在实际的项目中表现为多版本代码片段控制。
- 在代码的调式阶段,可以使用错误和警告信息指令来禁止编译不属于本功能的额外代码。
- 使用定义区域指令可以很好折叠和隐藏指定区域的代码片段。开发者可以更好的集中处理关键代码,在有着多个代码区域的项目十分的方便。
结语
😸 以上就是 C# 预处理器指令的介绍,希望能够对大家有所帮助。望大家多多支持,你们的支持就是笔者创作最大的动力!
相关文章:

【C#基础】C# 预处理器指令
序号系列文章8【C#基础】C# 面向对象编程9【C# 基础】C# 异常处理操作10【C#基础】C# 正则表达式文章目录前言1,预处理器指令的概念2,预处理器指令的定义与使用2.1,可为空上下文2.2,定义符号2.3,条件编译2.4࿰…...

摸鱼用python获取弹幕的两种方式【前者简单,后者数据好看】
嗨害大家好鸭!我是小熊猫~ 相信大家对于 “弹幕文化” 已经相当熟悉啦 你不是一个人在看——这就是弹幕网站的存在感。 它形成了新的“抱团”观看模式, 也真正实现了无时空距离的社交。 有网友表示,弹幕简直比剧情还有趣。 看似简单的寥寥…...

【C++】继承与多态
目录前言1. 继承1.1 继承的概念1.2 继承的定义1.3 切片赋值1.4 继承中的作用域1.5 派生类的默认成员函数1.6 继承与友元、静态成员1.7 多继承、菱形继承、菱形虚拟继承1.7.1 区分单继承与多继承1.7.2 菱形继承1.7.3 菱形虚拟继承1.7.4 菱形虚拟继承的原理2. 多态2.1 概念2.2 多…...

每日分享(微信社区小程序/h5/圈子论坛贴吧交友/博客/社交)
1.Java单元测试实战 高清PDF中文版 Java单元测试实战来自于作者多年来的单元测试实践,最初发表在阿里内网的ATA上,成为了很多阿里同学单元测试学习的必读文章。很多程序员认为单元测试会花费大量的时间,因此他们写单元测试的意愿比较低&…...

第51章 初识第3方阿里云短信验证发送服务
1 第3方阿里云短信验证发送服务准备工作 2 其它第3方短信发送服务平台 当前常用第3方短信发送服务平台还有容联云和凯信通过,在配置上来说阿里云和容联云配置都比较复杂,网上程序集成示例完善,资费灵活。凯信通配置十分简单只要在程序中指定其…...

CSGO社区服搭建服务器架设游戏服务端教程
CSGO社区服搭建服务器架设游戏服务端教程 我是艾西,上一篇说了搭建CSGO服务器需要准备服务器以及安装好所需要的环境,那么今天说一下CSGO社区私人服务器怎么搭建游戏服务端 搭建CSGO服务器比较简单,Valve开发者社区wiki也给出了安装指导&…...

【Linux学习】基础IO——系统调用 | 文件描述符fd | 重定向
🐱作者:一只大喵咪1201 🐱专栏:《Linux学习》 🔥格言:你只管努力,剩下的交给时间! 基础IO🍎文件操作🍉使用C接口进行文件操作🍉文件操作的系统调…...

PLC实验—西门子S7 1200读取超声波传感器数据
PLC实验—西门子S7 1200读取超声波传感器数据 US-016超声波测距模块 实验箱上是US-016超声波测距模块,其有关信息可以看实验室的博客 US-016超声波测距模块 1号Pin:接VCC电源(直流5V) 2号Pin:量程设置引脚ÿ…...

一次Linux系统密码修改失败事件
一、事件描述 某业务系统采用移动云主机,某次因误操作导致移动云内嵌密码管理相关Pga进程导致页面无法修改密码,东移动云主机web终端登录也无法修改,密码错误次数最大已无法登录,无奈只能重启主机,修改密码;…...

C语言循环控制语句Break,goto,continue语句讲解
循环控制语句改变你代码的执行顺序。通过它你可以实现代码的跳转。 C 语言中 break 语句有以下两种用法: 当 break 语句出现在一个循环内时,循环会立即终止,且程序流将继续执行紧接着循环的下一条语句。 它可用于终止 switch 语句中的一个 …...

Zabbix“专家坐诊”第183期问答汇总
问题一 Q:老师,请问一下zabbix采集的数据怎么过滤,获取数据是nottime20:30 notafter3,怎么过滤出netafter3 ?谢谢。 A:过滤器设置如下图。 问题二 Q:大佬,请问一下被管节点部署了…...

以太网协议和DNS
目录 🐕今日良言:跨过困难,去迎接更好的自己. 🐳一、以太网桢格式 🐳二、DNS 🐕今日良言:跨过困难,去迎接更好的自己. 🐳一、以太网桢格式 数据链路层考虑的是相邻两个节点(通过网线/光纤/无线直接相连的两个设备…...

【设计模式】原型模式与建造者模式
原型模式 原型模式是指通过原型实例指定创建对象的种类,然后通过拷贝的方式创建新的对象。属于创建型模式 原型模式的核心在于拷贝原型对象,主要用于对对象的复制。当你需要通过一大段get/set方法去构建对象的时候,就可以考虑使用原型模式了…...
QT之Http请求
今天我们介绍一下QT的http请求,这里有post和get两种方式 一、post请求方式:参数分为网址和具体请求值两个部分,有时候还需要设置头信息,看具体情况定 1 void MainWindow::sendPostRequest()2 {3 QNetworkAccessManager *m_pH…...

何谓dB , dB怎么理解?
dB 是什么单位 ?愈低愈好吗?对于声频 ( 声学及电子声学 ) 方面的单位,它是以分贝(decibel ,dB ) 来做结果的。斯多里一生专注于科学,1876 发明电话,我们都知道贝尔发明了电话,然而重要的是,他发现我们人类耳朵对声音…...

【数据聚类|深度聚类】Unsupervised Deep Embedding for Clustering Analysis(DEC)论文研读
DEC算法由两部分组成 第一部分会预训练一个SDAE模型;第二部分选取SDAE模型中的Encoder部分,加入聚类层,然后最小化KL散度进行训练聚类Absratct 提出了一种利用深度神经网络同时进行表征学习和聚类分配的方法,称之为深度嵌入聚类。该方法学习从数据空间到低纬空间的映射,并…...

Nuxt.js项目开发过程遇到的问题以及对Nuxt.js的学习与总结
文章目录📋前言💻Nuxtjs3快速了解🎯nuxtjs是什么?官网是这样介绍它的。🎯关于nuxtjs的SSR开发🧩SSR应用场景🧩nuxtjs的特性💻nuxtjs的初始目录结构🎯关于各个目录的解释&…...

JavaSE:异常机制
异常概念异常发生的原因用户输入非法数据要打开的文件不存在网络中断/JVM内存溢出(JVM是JRE的一部分。它是一个虚构出来的计算机)除0、非法参数等三种类型的异常,用以理解异常检查性异常【otherException】:程序员无法预见的&…...
Go mockito 使用说明 (github/mockey)
GitHub - bytedance/mockey: a simple and easy-to-use golang mock library Go mockito 是什么? mockey是一个简单易用的golang mock库,可以快速方便的mock函数和变量。目前广泛应用于字节跳动服务的单元测试编写。底层是monkey patch,通过在运行时重…...

Spring Boot+Vue前后端分离项目练习01之网盘项目的搭建
1.前期设计 一般看来,网盘系统主要实体包括:用户、存储信息、用户文件、文件、回收文件等基本功能点。 各实体对应的表结构如下所示: 表名:user(用户表) 字段名属性说明userIdbigint主键usernamevarcha…...
QMC5883L的驱动
简介 本篇文章的代码已经上传到了github上面,开源代码 作为一个电子罗盘模块,我们可以通过I2C从中获取偏航角yaw,相对于六轴陀螺仪的yaw,qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...

让AI看见世界:MCP协议与服务器的工作原理
让AI看见世界:MCP协议与服务器的工作原理 MCP(Model Context Protocol)是一种创新的通信协议,旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天,MCP正成为连接AI与现实世界的重要桥梁。…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...

JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...

使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...
探索Selenium:自动化测试的神奇钥匙
目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...
深度剖析 DeepSeek 开源模型部署与应用:策略、权衡与未来走向
在人工智能技术呈指数级发展的当下,大模型已然成为推动各行业变革的核心驱动力。DeepSeek 开源模型以其卓越的性能和灵活的开源特性,吸引了众多企业与开发者的目光。如何高效且合理地部署与运用 DeepSeek 模型,成为释放其巨大潜力的关键所在&…...
Pydantic + Function Calling的结合
1、Pydantic Pydantic 是一个 Python 库,用于数据验证和设置管理,通过 Python 类型注解强制执行数据类型。它广泛用于 API 开发(如 FastAPI)、配置管理和数据解析,核心功能包括: 数据验证:通过…...