【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…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...

React19源码系列之 事件插件系统
事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

ardupilot 开发环境eclipse 中import 缺少C++
目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...
【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)
升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点,但无自动故障转移能力,Master宕机后需人工切换,期间消息可能无法读取。Slave仅存储数据,无法主动升级为Master响应请求ÿ…...

Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...

2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖
在Vuzix M400 AR智能眼镜的助力下,卢森堡罗伯特舒曼医院(the Robert Schuman Hospitals, HRS)凭借在无菌制剂生产流程中引入增强现实技术(AR)创新项目,荣获了2024年6月7日由卢森堡医院药剂师协会࿰…...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...