C# 预处理器指令的用法

 更新时间:2023年04月16日 10:52:18   作者:哈桑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");
        #else
            Console.WriteLine("condition is not defined");
        #endif
            Console.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 VERBOSE
                Console.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");
        #else
            Console.WriteLine("condition is not defined");
        #endif
            Console.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# String扩展 让你在PadLeft和PadRight时不再受单双字节问题困扰

    c# String扩展 让你在PadLeft和PadRight时不再受单双字节问题困扰

    这篇文章主要介绍了c# String扩展 让你在PadLeft和PadRight时不再受单双字节问题困扰,需要的朋友可以参考下
    2020-04-04
  • C#开发Winform程序调用存储过程

    C#开发Winform程序调用存储过程

    这篇文章介绍了C#开发Winform程序调用存储过程的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-05-05
  • WPF实现动画效果(一)之基本概念

    WPF实现动画效果(一)之基本概念

    这篇文章介绍了WPF实现动画效果之基本概念,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • Unity3D实现飞机大战游戏(1)

    Unity3D实现飞机大战游戏(1)

    这篇文章主要为大家详细介绍了Unity3D实现飞机大战游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-06-06
  • 使用C#代码向Word文档添加文档属性的操作指南

    使用C#代码向Word文档添加文档属性的操作指南

    文档属性是指描述文档的一组信息,所有 Word 文档都自带一组内置的文档属性,在本文中,我们将介绍如何使用 Spire.Doc for .NET,通过 C# 和 VB.NET 向 Word 文档添加这些文档属性,需要的朋友可以参考下
    2025-12-12
  • C#操作Word中水印添加和移除的完整指南

    C#操作Word中水印添加和移除的完整指南

    在软件系统开发过程中,文档处理功能往往是企业级应用的重要组成部分,本文将详细介绍如何利用 Spire.Doc for .NET 组件,通过 C# 代码实现 Word 文档中文本水印的添加、图片水印的添加以及已有水印的移除操作,有需要的小伙伴可以了解下
    2026-05-05
  • C#中timer类的用法总结

    C#中timer类的用法总结

    System.Windows.Forms.Timer是应用于WinForm中的,它是通过Windows消息机制实现的,类似于VB或Delphi中的Timer控件,内部使用API SetTimer实现的。它的主要缺点是计时不精确,而且必须有消息循环
    2013-10-10
  • Unity ScrollView实现自动吸附效果

    Unity ScrollView实现自动吸附效果

    这篇文章主要为大家详细介绍了Unity ScrollView实现自动吸附效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-07-07
  • C#利用IDbCommand实现通用数据库脚本执行程序

    C#利用IDbCommand实现通用数据库脚本执行程序

    在.net 应用中,在数据库中执行脚本程序是经常用到的功能,如数据操作(新增、修改、删除等),执行一个存储过程等,本文将介绍如何通过利用IDbCommand 实现通用数据库脚本执行程序,感兴趣的朋友可以参考下
    2024-04-04
  • 基于C#实现Modbus RTU通信

    基于C#实现Modbus RTU通信

    本文主要介绍了使用C#和Modbus RTU模式与下位机进行通信,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2026-03-03

最新评论