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

【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&#xff0c;预处理器指令的概念2&#xff0c;预处理器指令的定义与使用2.1&#xff0c;可为空上下文2.2&#xff0c;定义符号2.3&#xff0c;条件编译2.4&#xff0…...

摸鱼用python获取弹幕的两种方式【前者简单,后者数据好看】

嗨害大家好鸭&#xff01;我是小熊猫~ 相信大家对于 “弹幕文化” 已经相当熟悉啦 你不是一个人在看——这就是弹幕网站的存在感。 它形成了新的“抱团”观看模式&#xff0c; 也真正实现了无时空距离的社交。 有网友表示&#xff0c;弹幕简直比剧情还有趣。 看似简单的寥寥…...

【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单元测试实战来自于作者多年来的单元测试实践&#xff0c;最初发表在阿里内网的ATA上&#xff0c;成为了很多阿里同学单元测试学习的必读文章。很多程序员认为单元测试会花费大量的时间&#xff0c;因此他们写单元测试的意愿比较低&…...

第51章 初识第3方阿里云短信验证发送服务

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

CSGO社区服搭建服务器架设游戏服务端教程

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

【Linux学习】基础IO——系统调用 | 文件描述符fd | 重定向

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《Linux学习》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; 基础IO&#x1f34e;文件操作&#x1f349;使用C接口进行文件操作&#x1f349;文件操作的系统调…...

PLC实验—西门子S7 1200读取超声波传感器数据

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

一次Linux系统密码修改失败事件

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

C语言循环控制语句Break,goto,continue语句讲解

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

Zabbix“专家坐诊”第183期问答汇总

问题一 Q&#xff1a;老师&#xff0c;请问一下zabbix采集的数据怎么过滤&#xff0c;获取数据是nottime20:30 notafter3&#xff0c;怎么过滤出netafter3 &#xff1f;谢谢。 A&#xff1a;过滤器设置如下图。 问题二 Q&#xff1a;大佬&#xff0c;请问一下被管节点部署了…...

以太网协议和DNS

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

【设计模式】原型模式与建造者模式

原型模式 原型模式是指通过原型实例指定创建对象的种类&#xff0c;然后通过拷贝的方式创建新的对象。属于创建型模式 原型模式的核心在于拷贝原型对象&#xff0c;主要用于对对象的复制。当你需要通过一大段get/set方法去构建对象的时候&#xff0c;就可以考虑使用原型模式了…...

QT之Http请求

今天我们介绍一下QT的http请求&#xff0c;这里有post和get两种方式 一、post请求方式&#xff1a;参数分为网址和具体请求值两个部分&#xff0c;有时候还需要设置头信息&#xff0c;看具体情况定 1 void MainWindow::sendPostRequest()2 {3 QNetworkAccessManager *m_pH…...

何谓dB , dB怎么理解?

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

【数据聚类|深度聚类】Unsupervised Deep Embedding for Clustering Analysis(DEC)论文研读

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

Nuxt.js项目开发过程遇到的问题以及对Nuxt.js的学习与总结

文章目录&#x1f4cb;前言&#x1f4bb;Nuxtjs3快速了解&#x1f3af;nuxtjs是什么&#xff1f;官网是这样介绍它的。&#x1f3af;关于nuxtjs的SSR开发&#x1f9e9;SSR应用场景&#x1f9e9;nuxtjs的特性&#x1f4bb;nuxtjs的初始目录结构&#x1f3af;关于各个目录的解释&…...

JavaSE:异常机制

异常概念异常发生的原因用户输入非法数据要打开的文件不存在网络中断/JVM内存溢出&#xff08;JVM是JRE的一部分。它是一个虚构出来的计算机&#xff09;除0、非法参数等三种类型的异常&#xff0c;用以理解异常检查性异常【otherException】&#xff1a;程序员无法预见的&…...

Go mockito 使用说明 (github/mockey)

GitHub - bytedance/mockey: a simple and easy-to-use golang mock library Go mockito 是什么? mockey是一个简单易用的golang mock库&#xff0c;可以快速方便的mock函数和变量。目前广泛应用于字节跳动服务的单元测试编写。底层是monkey patch&#xff0c;通过在运行时重…...

Spring Boot+Vue前后端分离项目练习01之网盘项目的搭建

1.前期设计 一般看来&#xff0c;网盘系统主要实体包括&#xff1a;用户、存储信息、用户文件、文件、回收文件等基本功能点。 各实体对应的表结构如下所示&#xff1a; 表名&#xff1a;user&#xff08;用户表&#xff09; 字段名属性说明userIdbigint主键usernamevarcha…...

RocketMQ延迟消息机制

两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数&#xff0c;对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后&#xf…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

大语言模型如何处理长文本?常用文本分割技术详解

为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

linux 错误码总结

1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

SpringCloudGateway 自定义局部过滤器

场景&#xff1a; 将所有请求转化为同一路径请求&#xff08;方便穿网配置&#xff09;在请求头内标识原来路径&#xff0c;然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...

Redis数据倾斜问题解决

Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中&#xff0c;部分节点存储的数据量或访问量远高于其他节点&#xff0c;导致这些节点负载过高&#xff0c;影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...

10-Oracle 23 ai Vector Search 概述和参数

一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI&#xff0c;使用客户端或是内部自己搭建集成大模型的终端&#xff0c;加速与大型语言模型&#xff08;LLM&#xff09;的结合&#xff0c;同时使用检索增强生成&#xff08;Retrieval Augmented Generation &#…...

【Java学习笔记】BigInteger 和 BigDecimal 类

BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点&#xff1a;传参类型必须是类对象 一、BigInteger 1. 作用&#xff1a;适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...

Mysql中select查询语句的执行过程

目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析&#xff08;Parser&#xff09; 2.4、执行sql 1. 预处理&#xff08;Preprocessor&#xff09; 2. 查询优化器&#xff08;Optimizer&#xff09; 3. 执行器…...

Java求职者面试指南:计算机基础与源码原理深度解析

Java求职者面试指南&#xff1a;计算机基础与源码原理深度解析 第一轮提问&#xff1a;基础概念问题 1. 请解释什么是进程和线程的区别&#xff1f; 面试官&#xff1a;进程是程序的一次执行过程&#xff0c;是系统进行资源分配和调度的基本单位&#xff1b;而线程是进程中的…...