澳门新萄京官方网站-www.8455.com-澳门新萄京赌场网址

澳门新萄京官方网站:中的预编译指令介绍,预

2019-08-31 作者:www.8455.com   |   浏览(88)

欲练神功,引刀自宫。为了制止内部存款和储蓄器管理的烦躁,Java咔嚓一下,把指针砍掉了。当年.Net也紧跟着前卫,咔嚓了弹指间,化名小桂子,登堂入室进了皇宫。康熙帝往上面一抓:咦?还在?——原本是假太监韦小宝。

本文出处:熊小熊的博客    

下面对C#中的预编写翻译指令进行介绍:

1、#define和#undef

打开unsafe选项,C#指南针就biu的登时蹦出来了。指针很强劲,没要求扬弃这一强硬的工具。诚然,在大多处境下用不上指针,但在一定的场所下依旧要求动用的。比方:

下面对C#中的预编写翻译指令展开介绍:

1.#define和#undef

     用法:

(1)大面积的演算中使用指针来增长质量;

1.#define和#undef

用法:

          #define DEBUG

(2)与非托管代码举行交互;

用法:

      #define DEBUG 
      #undef DEBUG

          #undef DEBUG

(3)在实时程序中动用指针,自行保管内存和对象的生命周期,以调整和裁减GC的承负。

      #define DEBUG 
      #undef DEBUG

      #define告诉编写翻译器,小编定义了三个DEBUG的叁个符号,他好像二个变量,可是它未有现实的值,能够将它看为三个标识而已。#undef便是去除这几个标志的概念。要是符号DEBUG没概念过,则#undef不起效率,不然#define不起成效。二者都必得放在源代码在此之前。二者的逐个看代码的逐个:

    #define告诉编写翻译器,笔者定义了一个DEBUG的一个标志,他临近一个变量,不过它未有实际的值,能够将它看为三个符号而已。#undef正是删除这些符号的定义。如果符号DEBUG没概念过,则#undef不起功效,不然#define不起效率。二者都必须放在源代码以前。二者的各类看代码的逐一:

此时此刻使用指针的严重性语言是C和C 。但是出于语法限制,C和C 中的指针的游戏的方法很枯燥,在C#中,能够拓宽更优雅更加有意思的游戏的方法。本文是《重新认知C#: 玩转指针》一文的续篇,首假设对《重新认知C#: 玩转指针》内容开展总括和改正。

      #define告诉编写翻译器,作者定义了贰个DEBUG的贰个标识,他就好像二个变量,可是它并未有切实可行的值,能够将它看为一个标志而已。#undef正是剔除那几个标志的概念。假若符号DEBUG没概念过,则#undef不起成效,否则#define不起作用。二者都必需放在源代码从前。二者的一一看代码的各种:

      #define DEBUG 
     #undef  DEBUG

    #define DEBUG

C#下使用指针有两大规模:

      #define DEBUG 
     #undef  DEBUG

      那样的话,DEBUG是从未概念的,假如两个换个顺序,编写翻译器就以为DEBUG被定义了

    #undef  DEBUG

(1)使用指针只可以操作struct,不可能操作class;

      那样的话,DEBUG是从未概念的,假诺双方换个顺序,编写翻译器就以为DEBUG被定义了

2.#if、#elif、#else、#endif

   那样的话,DEBUG是绝非概念的,如若两岸换个顺序,编写翻译器就认为DEBUG被定义了

(2)不可能在泛型类型代码中采纳未定义类型的指针。

2.#if、#elif、#else、#endif

      那些报告编译器实行编译代码的流程序调控制。思索上边代码:

2、#if、#elif、#else、#endif

第多个限制不可能突破,因而须要将指针操作的连串设为struct。struct 指针,恩,就把C#当更加好的C来用吧。对于第一个限制,写二个预管理器来解决难点。

      那些报告编写翻译器实行编写翻译代码的流水生产线调整。思索上面代码:

            #if DEBUG
                  Console.Write("debug");
            #elif RELEASE
                  Console.Write("release");
            #else
                  Console.Write("other");
            #endif

   这么些报告编写翻译器进行编写翻译代码的流程序调整制。思索下边代码:

上边是自己写的简短的C#预管理器的代码,不到200行:
1 using System;
2 using System.Collections.Generic;
3 using System.IO;
4 using System.Text;
5 using System.Text.RegularExpressions;
6
7 namespace Orc.Util.Csmacro
8 {
9 class Program
10 {
11 static Regex includeReg = new Regex("#regions include. s #endregion");
12 static Regex mixinReg = new Regex("(?<=#regions mixins)[s|S] (?=#endregion)");
13 ///
14 /// Csmacro [dir|filePath]
15 ///
16 /// 语法:
17 /// #region include ""
18 /// #endregion
19 ///
20 ///
21 ///
22 static void
23 #region include<>
24 Main
25 #endregion
26 (string[] args)
27 {
28 if (args.Length != 1)
29 {
30 PrintHelp();
31 return;
32 }
33
34 String filePath = args[0];
35
36 Path.GetDirectoryName(filePath);
37 String dirName = Path.GetDirectoryName(filePath);
38 #if DEBUG
39 Console.WriteLine("dir:" dirName);
40 #endif
41 String fileName = Path.GetFileName(filePath);
42 #if DEBUG
43 Console.WriteLine("file:" fileName);
44 #endif
45
46 if (String.IsNullOrEmpty(fileName))
47 {
48 Csmacro(new DirectoryInfo(dirName));
49 }
50 else
51 {
52 if (fileName.EndsWith(".cs") == false)
53 {
54 Console.WriteLine("Csmacro只可以管理后缀为.cs的源程序.");
55 }
56 else
57 {
58 Csmacro(new FileInfo(fileName));
59 }
60 }
61
62 Console.WriteLine("[Csmacro]:管理完成.");
63
64 #if DEBUG
65 Console.ReadKey();
66 #endif
67 }
68
69 static void Csmacro(DirectoryInfo di)
70 {
71 Console.WriteLine("[Csmacro]:进入目录" di.FullName);
72
73 foreach (FileInfo fi in di.GetFiles("*.cs", SearchOption.AllDirectories))
74 {
75 Csmacro(fi);
76 }
77 }
78
79 static void Csmacro(FileInfo fi)
80 {
81 String fullName = fi.FullName;
82 if (fi.Exists == false)
83 {
84 Console.WriteLine("[Csmacro]:文件子虚乌有-" fullName);
85 }
86 else if (fullName.EndsWith("_Csmacro.cs"))
87 {
88 return;
89 }
90 else
91 {
92 String text = File.ReadAllText(fullName);
93
94 DirectoryInfo parrentDirInfo = fi.Directory;
95
96 MatchCollection mc = includeReg.Matches(text);
97 if (mc == null || mc.Count == 0) return;
98 else
99 {
100 Console.WriteLine("[Csmacro]:管理文件" fullName);
101
102 StringBuilder sb = new StringBuilder();
103
104 Int32 from = 0;
105 foreach (Match item in mc)
106 {
107 sb.Append(text.Substring(from, item.Index - from));
108 from = item.Index item.Length;
109 sb.Append(Csmacro(parrentDirInfo, item.Value));
110 }
111
112 sb.Append(text.Substring(from, text.Length - from));
113
114 String newName = fullName.Substring(0, fullName.Length - 3) "_Csmacro.cs";
115 if (File.Exists(newName))
116 {
117 Console.WriteLine("[Csmacro]:删除旧文件" newName);
118 }
119 File.WriteAllText(newName, sb.ToString());
120 Console.WriteLine("[Csmacro]:生成文书" newName);
121 }
122 }
123 }
124
125 static String Csmacro(DirectoryInfo currentDirInfo, String text)
126 {
127 String outfilePath = text.Replace("#region", String.Empty).Replace("#endregion", String.Empty).Replace("include",String.Empty).Replace(""",String.Empty).Trim();
128 try
129 {
130 if (Path.IsPathRooted(outfilePath) == false)
131 {
132 outfilePath = currentDirInfo.FullName @"" outfilePath;
133 }
134 FileInfo fi = new FileInfo(outfilePath);
135 if (fi.Exists == false)
136 {
137 Console.WriteLine("[Csmacro]:文件" fi.FullName "不存在.");
138 return text;
139 }
140 else
141 {
142 return GetMixinCode(File.ReadAllText(fi.FullName));
143 }
144 }
145 catch (Exception ex)
146 {
147 Console.WriteLine("[Csmacro]:出现谬误(" outfilePath ")-" ex.Message);
148 }
149 finally
150 {
151 }
152 return text;
153 }
154
155 static String GetMixinCode(String txt)
156 {
157 Match m = mixinReg.Match(txt);
158 if (m.Success == true)
159 {
160 return m.Value;
161 }
162 else return String.Empty;
163 }
164
165 static void PrintHelp()
166 {
167 Console.WriteLine("Csmacro [dir|filePath]");
168 }
169 }
170 }

            #if DEBUG
                  Console.Write("debug");
            #elif RELEASE
                  Console.Write("release");
            #else
                  Console.Write("other");
            #endif

      以上代码就是说假若定义了DEBUG则输出debug,定义了RELEASE,则输出realse,不然输出other。假使定义了DEBUG和REALSE会如何啊?各位能够友善试一下。

#if DEBUG
   Console.Write("debug");
#elif RELEASE
    Console.Write("realse");
#else
    Console.Write("other");
#endif

然后编写翻译为 Csmacro.exe ,放入系统路线下。在急需使用预管理器的类型中增多Pre-build event command lind:

      以上代码就是说假设定义了DEBUG则输出debug,定义了RELEASE,则输出realse,不然输出other。假诺定义了DEBUG和REALSE会怎样呢?各位能够友善试一下。

3.#warning、#error

  以上代码正是说要是定义了DEBUG则输出debug,定义了RELEASE,则输出realse,不然输出other。若是定义了DEBUG和REALSE会怎样啊?各位可以本身试一下。

Csmacro.exe $(ProjectDir)

3.#warning、#error

      通过那八个钦定能够告知编写翻译器,出一个警告也许错误新闻。除了错误消息今后,编写翻译将终止。

3、#warning、#error

Visual Studio 有个很好用的重要字 “region” ,大家就把它看做大家预管理器的要害字。include 三个文件的语法是:

      通过这四个内定能够告诉编写翻译器,出一个告诫只怕错误消息。除了错误新闻现在,编写翻译将告一段落。

      参谋上边包车型大巴代码(C#在Debug状态下自行定义DEBUG标记,但Release状态不会自动定义RELEASE标记):

   通过那多少个钦命可以告知编写翻译器,出叁个告诫也许错误消息。除了错误音信以后,编写翻译将适可而止

region include "xxx.cs"

      参照他事他说加以考察下边包车型客车代码(C#在Debug状态下自行定义DEBUG标识,但Release状态不会活动定义RELEASE标记):

            #if DEBUG                         
                  #warning 现在是Debug状态
            #elif RELEASE
                  #warning 现在是Release状态
            #else
                  #error 并理解哪些状态
            #endif

   参照他事他说加以考察上面包车型地铁代码

endregion

一个文本中得以有三个 #澳门新萄京官方网站:中的预编译指令介绍,预处理器。region include 块。

被引述的文本无法整个援用,因为贰个C#文件中貌似包蕴有 using,namespace … 等,全部援引的话会报编写翻译错误。由此,在被引述文件中,须要通过首要字来分明被引述的内容:

            #if DEBUG                         
                  #warning 现在是Debug状态
            #elif RELEASE
                  #warning 现在是Release状态
            #else
                  #error 并领会哪些情形
            #endif

4.#region 和#endregion

#if DEBUG                                 ------〉该DEBUG假诺选中当前处境为DEBUG,则那几个默以为#define
   #warning “现在是Ddbug状态”
#elif RELEASE                            ------〉假设选中release状态以来,这些确未有暗许,不领悟自个儿试验的对不对
    #warning “现在是Realse状态”
#else
    #error“并驾驭怎么情况”
#endif

region mixin

4.#region 和#endregion

      这么些四个用来组成代码块

4、#region 和#endregion

endregion

这几个预管理器相比轻巧。被引述的文书中不得一纸空文一个 #region mixin 块,且在那一个region的中间,不能有其余的region块。

预管理器 Csmacro.exe 的功效就是找到全体 cs 文件中的 #region include 块,根据 #region include 路线找到被援引文件,将该公文中的 #region mixin 块 取出,替换进 #region include 块中,生成三个以_Csmacro.cs结尾的新文件 。

由于C#的八个语法糖“partial” 和 “using”,预管理器蛮好用。若无那七个语法糖,预管理器会非常不好看陋不堪。(哪个人说语法糖没价值!一些比一点都不大的语法糖,足以完毕新的编制程序范式。)

partial 关键字 能够确定保障一个档次的代码存在几个不等的源文件中,那保障了预处理器的施行,您能够像写正常的代码同样编写公共部分代码,而且符合规律编写翻译。

using 关键字可以为项目钦赐三个的昵称。那是四个不值一提的语法糖,却在本文中拾分主要:它可感觉差别的种类内定四个一模一样的种类小名。之所以引进预管理器,便是为着复用富含指针的代码。我们得以将代码抽象成两片段:变化部分和不改变部分。一般的话,变化部分是项指标型别,如若还大概有另外非类型的转换,大家也足以将那几个变化封装成新的品种。那样一来,大家得以将调换的品种放在源文件的顶上部分,使用using 关键字,命名称为固定的小名。然后把不改变部分的代码,放在 #region mixin 块中。这样的话,让大家须要 #region include 时,只须要在 #region include 块的先头(需求在namespace {} 的外表)为项目别称钦命新的品类。

比如表明,位图依照像素的格式能够分为很各样,这里假如有二种图像,一种是像素是三个Byte的灰度图像ImageU8,贰个是像素是贰个Argb32的彩色图像ImageArgb32。ImageU8代码如下:

1 public class ImageU8
2 {
3 public Int32 Width { get; set; }
4 public Int32 Height { get; set; }
5
6 public unsafe Byte* Pointer;
7 public unsafe void SetValue(Int32 row, Int32 col, Byte value)
8 {
9 Pointer[row * Width col] = value;
10 }
11 }

在 ImageArgb32 中,大家也要写重复的代码:

1 public class ImageArgb32
2 {
3 public Int32 Width { get; set; }
4 public Int32 Height { get; set; }
5
6 public unsafe Argb32* Pointer;
7 public unsafe void SetValue(Int32 row, Int32 col, Argb32 value)
8 {
9 Pointer[row * Width col] = value;
10 }
11 }

对于 Width和Height属性,大家可以创建基类来进展抽象和复用,不过,对于m_pointer和SetValue方法,假使放在基类中,则要求抹去类型音讯,且变的格外丑陋。由于C#不帮助泛型类型的指针,也无力回天领取为泛型代码。

应用 Csmacro.exe 预管理器,我们就能够很好的拍卖。

首先,创设一个模板文件 Image_Template.cs

代码

1 using TPixel = System.Byte;
2
3 using System;
4
5 namespace XXX.Hidden
6 {
7 class Image_Template
8 {
9 public Int32 Width { get; set; }
10 public Int32 Height { get; set; }
11
12 #region mixin
13
14 public unsafe TPixel* Pointer;
15 public unsafe void SetValue(Int32 row, Int32 col, TPixel value)
16 {
17 Pointer[row * Width col] = value;
18 }
19
20 #endregion
21 }
22 }

然后建设构造多少个基类 BaseImage,再从BaseImage派生ImageU8和ImageArgb32。四个派生类都是 partial 类:

下边大家创建二个 ImageU8_ClassHelper.cs 文件,来 #region include 引用上面的模板文件:

1 using TPixel = System.Byte;
2
3 using System;
4 namespace XXX
5 {
6 public partial class ImageU8
7 {
8 #region include "Image_Template.cs"
9 #endregion
10 }
11 }

编写翻译,编写翻译器会自动生成文件 “ImageU8_ClassHelper_Csmacro.cs” 。将以此文件引进项目中,编写翻译通过。那几个文件内容是:

代码

1 using TPixel = System.Byte;
2
3 using System;
4 namespace XXX
5 {
6 public partial class ImageU8
7 {
8
9 public unsafe TPixel* Pointer;
10 public unsafe void SetValue(Int32 row, Int32 col, TPixel value)
11 {
12 Pointer[row * Width col] = value;
13 }
14
15 }
16 }

对此 ImageArgb32 类也能够拓宽类似操作。

从那些例子能够看看,使用 partial 关键字,能够让原代码、模板代码、ClassHelper代码三者共存。使用 using 关键字,能够分别出代码中变化的一对出来。

上边是自家写的图像操作的某个模板代码:

(1)通过沙盘提供指针和索引器:

代码

1 using TPixel = System.Byte;
2 using TCache = System.Int32;
3 using TKernel = System.Int32;
4
5 using System;
6 using System.Collections.Generic;
7 using System.Text;
8
9 namespace Orc.SmartImage.Hidden
10 {
11 public abstract class Image_Template : UnmanagedImage

(2)通过沙盘提供常用的操作和兰姆da表明式援助

代码

1 using TPixel = System.Byte;
2 using TCache = System.Int32;
3 using TKernel = System.Int32;
4
5 using System;
6 using System.Collections.Generic;
7 using System.Text;
8
9 namespace Orc.SmartImage.Hidden
10 {
11 static class ImageClassHelper_Template
12 {
13 #region mixin
14
15 public unsafe delegate void ActionOnPixel(TPixel* p);
16 public unsafe delegate void ActionWithPosition(Int32 row, Int32 column, TPixel* p);
17 public unsafe delegate Boolean PredicateOnPixel(TPixel* p);
18
19 public unsafe static void ForEach(this UnmanagedImage

相配lambda表明式,用起来很爽。在措施“FindTemplate”中,有这一句:

if (pattern >= 0 && srcStart[rr * stride cc] != pattern)

其中 srcStart[rr * stride cc] 是 TPixel 不定类型,而 pattern 是 int 类型,两者之间供给实行相比,可是实际不是兼具的种类都提供和整数之间的 != 操作符。为此,作者创立了个新的模版 TPixel_Template。

(3)通过沙盘提供 != 操作符 的定义

1 using TPixel = System.Byte;
2 using System;
3
4 namespace Orc.SmartImage.Hidden
5 {
6 public struct TPixel_Template
7 {
8 /*
9 #region mixin
10
11 public static Boolean operator ==(TPixel lhs, int rhs)
12 {
13 throw new NotImplementedException();
14 }
15
16 public static Boolean operator !=(TPixel lhs, int rhs)
17 {
18 throw new NotImplementedException();
19 }
20
21 public static Boolean operator ==(TPixel lhs, double rhs)
22 {
23 throw new NotImplementedException();
24 }
25
26 public static Boolean operator !=(TPixel lhs, double rhs)
27 {
28 throw new NotImplementedException();
29 }
30
31 public static Boolean operator ==(TPixel lhs, float rhs)
32 {
33 throw new NotImplementedException();
34 }
35
36 public static Boolean operator !=(TPixel lhs, float rhs)
37 {
38 throw new NotImplementedException();
39 }
40
41 #endregion
42
43 */
44 }
45 }

这里,在 #region mixin 块被疏解掉了,不注释掉编写翻译器会报错。注释之后,不会听得多了就能说的清楚程序预管理。

通过 ClassHelper类来使用模板:

代码

1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4
5 namespace Orc.SmartImage
6 {
7 using TPixel = Argb32;
8 using TCache = System.Int32;
9 using TKernel = System.Int32;
10
11 public static partial class ImageArgb32ClassHelper
12 {
13 #region include "ImageClassHelper_Template.cs"
14 #endregion
15 }
16
17 public partial class ImageArgb32
18 {
19 #region include "Image_Template.cs"
20 #endregion
21 }
22
23 public partial struct Argb32
24 {
25 #region include "TPixel_Template.cs"
26 #endregion
27 }
28 }

出于 Argb32 未提供和 int 之间的可比,由此,在此间 #region include "TPixel_Template.cs"。而Byte能够与int相比较,因而,在ImageU第88中学,就不必要#region include "TPixel_Template.cs":

3 using System;
4 using System.Collections.Generic;
5 using System.Text;
6
7 namespace Orc.SmartImage
8 {
9 using TPixel = System.Byte;
10 using TCache = System.Int32;
11 using TKernel = System.Int32;
12
13 public static partial class ImageU8ClassHelper
14 {
15 #region include "ImageClassHelper_Template.cs"
16 #endregion
17 }
18
19 public partial class ImageU8
20 {
21 #region include "Image_Template.cs"
22 #endregion
23 }
24 }

      这几个八个用来组成代码块

5.#line

  那么些多少个用来组合代码块

是或不是很风趣啊?壮大的指针,结合C#有力的语法和快捷编写翻译,至少在图像管理这一块是很好用的。

 预管理器指令的发端都有标记#。

5.#line

      那么些命令能够改动编译器在警戒和错误音讯中显示的文本名和行号新闻,用#line default把行号苏醒为暗中认可的行号。

5、#line (这一个钦命的施用不太明白,参考MSDN)

1. define 和 #undef

  #define 的用法如下所示: #define DEBUG

  它报告编写翻译器存在给定名称的标志,在本例中是DEBUG。那有一点点类似于声贝因美(Beingmate)个变量,但这一个变量并从未真的的值,只是存在而已。

  那些符号不是实在代码的一片段,而只在编写翻译器编写翻译代码时存在。在C#代码中它并未有别的意义。

  #undef 正好相反—— 它删除符号的概念: #undef DEBUG

  即使符号不设有,#undef 就平素不其余意义。同样,若是符号已经存在,则#define 也不起成效。必需把#define 和#undef 命令放在C#源文件的发端地点,在注明要编写翻译的别的对象的代码以前。

  #define 本人并不曾什么用,但与其他预管理器指令(极度是#if)结合使用时,它的成效就特别有力了。

  这里应留心一般C#语法的部分转移。预管理器指令不用分号结束,一般一行上唯有一条命令。那是因为对于预管理器指令,C#不再要求命令使用分号实行分隔。假设它碰到一条预处理器指令,就能够假定下一条命令在下一行上。

      那几个命令能够变动编写翻译器在警告和错误音信中展现的文件名和行号新闻,用#line default把行号苏醒为暗中认可的行号。

      #line [ number ["file_name"] | default ]

  这几个命令能够改换编写翻译器在告诫和错误音讯中呈现的公文名和行号新闻,用#line default把行号恢复生机为默许的行号。

1. if、#elif、#else 和#endif

  那一个指令告诉编写翻译器是还是不是要编写翻译有个别代码块。思虑下边包车型客车法子:

1 int DoSomeWork(double x)
2 {
3 // do something
4 #if DEBUG
5 Console.WriteLine("x is " x);
6 #endif
7 }

  这段代码会像过去那么编写翻译,但Console.WriteLine 命令饱含在#if 子句内。

  那行代码独有在眼前的#define 命令定义了符号DEBUG 后才施行。

  当编写翻译器蒙受#if 语句后,将先反省不非亲非故系的暗号是还是不是留存,若是符号存在,就编写翻译#if 子句中的代码。不然,编写翻译器会忽略全数的代码,直到遇到相配的#endif 指令截至。

  一般是在调治时定义符号DEBUG,把与调度相关的代码放在#if 子句中。在产生了调养后,就把#define 语句注释掉,全数的调治代码会奇迹般地消失,可实行文件也会变小,最后客户不会被那一个调节和测验消息弄糊涂(分明,要做越来越多的测量检验,确认保证代码在未有概念DEBUG 的情况下也能工作)。

  那项技艺在C 和C 编制程序中极度布满,称为条件编写翻译(conditional compilation)。

  #elif (=else if)和#else 指令可以用在#if 块中,其含义极其直观。也足以嵌套#if 块:

      #line [ number ["file_name"] | default ]

      number
            要为源代码文件中前边的行钦赐的号子。
      "file_name"(可选)
            希望出现在编写翻译器输出中的文件名。暗许景况下,使用源代码文件的实际名称。文件名必须括在双引号 ("") 中。
      default
            重新设置文件中的行编号。
      备注
            #line 恐怕由生成进度中的自动中间步骤使用。比如,借使中间步骤从原始的源代码文件中移除行,不过你仍希望编译器基于文件中的原始行号生成输出,则足以移除行,然后用 #line 模拟原始行号。

上面包车型客车演示表达如何报告与行号关联的七个警示。#line 200 指令迫使行号为 200(就算暗中认可值为 #7)。另一行 (#9) 作为私下认可 #line 指令 的结果跟在平时类别后。
// preprocessor_line.cs
public class MyClass2
{
   public static void Main()
   {
      #line 200
      int i;   // CS0168 on line 200
      #line default
      char c;   // CS0168 on line 9
   }
}

define ENTERPRISE

      number
            要为源代码文件中前边的行钦赐的数码。
      "file_name"(可选)
            希望现身在编写翻译器输出中的文件名。暗许景况下,使用源代码文件的莫过于名称。文件名必得括在双引号 ("") 中。
      default
            复位文件中的行编号。
      备注
            #line 恐怕由生成进度中的自动中间步骤使用。举例,假设中间步骤从原本的源代码文件中移除行,不过你仍盼望编写翻译器基于文件中的原始行号生成输出,则可以移除行,然后用 #line 模拟原始行号。

      下边包车型客车示范表达什么报告与行号关联的多少个警示。#line 200 指令迫使行号为 200(固然暗中同意值为 #7)。另一行 (#9) 作为暗中同意 #line 指令 的结果跟在普通类别后。

示例 2
下边包车型客车亲自去做说明调节和测量试验器怎么着忽略代码中的遮掩行。运营此示例时,它将呈现三行文本。但是,当设置如示例所示的断点并按 F10 键逐句通过代码时,您将见到调节和测验器忽略了隐敝行。另请留心,纵然在隐敝行上设置断点,调节和测量检验器仍会忽视它。
// preprocessor_linehidden.cs
using System;
class MyClass
{
   public static void Main()
   {
      Console.WriteLine("Normal line #1.");   // Set a break point here.
      #line hidden
      Console.WriteLine("Hidden line.");
      #line default
      Console.WriteLine("Normal line #2.");
   }
}

define W2K

// further on in the file

      上面包车型客车以身作则表达什么报告与行号关联的七个警示。#line 200 指令迫使行号为 200(即便暗中认可值为 #7)。另一行 (#9) 作为默许 #line 指令 的结果跟在常常体系后。

示例1:

if ENTERPRISE

// do something

示例1:

      // preprocessor_line.cs
      public class MyClass2
      {
            public static void Main()
            {
                  #line 200
                  int i;       // line 200
                  #line default
                  char c;  // line 9
            }
      }

if W2K

// some code that is only relevant to enterprise
// edition running on W2K

      // preprocessor_line.cs
      public class MyClass2
      {
            public static void Main()
            {
                  #line 200
                  int i;       // line 200
                  #line default
                  char c;  // line 9
            }
      }

示例2:

endif

示例2:

      上面包车型地铁身体力行表明调节和测量检验器怎么着忽略代码中的掩盖行。运转此示例时,它将显得三行文本。可是,当设置如示例所示的断点并按 F10 键逐句通过代码时,您将见到调节和测量检验器忽略了隐敝行。另请留神,纵然在遮蔽行上设置断点,调节和测量试验器仍会忽略它。

elif PROFESSIONAL

// do something else

      上面包车型地铁亲自过问表达调节和测验器怎样忽略代码中的遮盖行。运营此示例时,它将显示三行文本。不过,当设置如示例所示的断点并按 F10 键逐句通过代码时,您将见到调试器忽略了隐蔽行。另请留神,就算在遮蔽行上设置断点,调节和测量检验器仍会忽视它。

     // preprocessor_linehidden.cs
      using System;
      class MyClass
      {
            public static void Main()
            {
                  Console.WriteLine("Normal line #1.");  // Set a break point here.
                  #line hidden
                  Console.WriteLine("Hidden line.");
                  #line default
                  Console.WriteLine("Normal line #2.");
            }
      }

else

// code for the leaner version

     // preprocessor_linehidden.cs
      using System;
      class MyClass
      {
            public static void Main()
            {
                  Console.WriteLine("Normal line #1.");  // Set a break point here.
                  #line hidden
                  Console.WriteLine("Hidden line.");
                  #line default
                  Console.WriteLine("Normal line #2.");
            }
      }

6.#pragma

endif

与C 中的境况不一,使用#if 不是有标准地编写翻译代码的独一方法,C#还通过Conditional 个性提供了另一种机制。
  #if 和#elif 还扶助一组逻辑运算符“!”、“==”、“!=”和“||”。如若符号存在,就被感觉是true,不然为false,比如:

1 #if W2K && (ENTERPRISE==false) // if W2K is defined but ENTERPRISE isn't

6.#pragma

       能够压制或复苏内定的编写翻译警告。与命令行选项不一样,#pragma指令能够在类和格局上施行,对遏制什么警告和遏制的时刻进行越来越小巧的操纵。

1. warning 和 #error

  另五个特别实用的预管理器指令是#warning 和#error,当编写翻译器碰到它们时,会独家发生警告或不当。假如编写翻译器遭遇#warning 指令,会给顾客展现#warning 指令后边的文本,之后编写翻译继续拓宽。假使编写翻译器碰到#error 指令,就能给顾客显示后边的公文,作为一条编写翻译错误新闻,然后会立时退出编写翻译,不会生成IL 代码。

  使用这两条指令能够检查#define 语句是或不是做错了如何事,使用#warning 语句可以唤起本人施行有些操作:

1 #if DEBUG && RELEASE
2 #error "You've defined DEBUG and RELEASE simultaneously!"
3 #endif
4 #warning "Don't forget to remove this line before the boss tests the code!"
5 Console.WriteLine("I hate this job.");

       能够遏制或复苏钦定的编译警告。与命令行选项分裂,#pragma指令能够在类和艺术上实行,对抑制什么警告和防止的日子展开越来越精细的调控。

       #pragma warning disable 169
       public class Aclass
       {
               int nFiled;
       }
       #pragma warning restore 169

1. region 和#endregion

  #region 和#endregion 指令用于把一段代码标识为有给定称号的三个块,如下所示。

1 #region Member Field Declarations
2 int x;
3 double d;
4 Currency balance;
5 #endregion

  那看起来就像并未有啥样用,它不影响编写翻译进度。那几个指令的亮点是它们得以被一些编辑器度和胆识别,蕴含Visual Studio .NET 编辑器。那么些编辑器可以应用那些指令使代码在荧屏上越来越好地布局。

       #pragma warning disable 169
       public class Aclass
       {
               int nFiled;
       }
       #pragma warning restore 169

1. line

  #line 指令能够用于转移编写翻译器在告诫和错误消息中显得的公文名和行号音讯。那条指令用得并十分少。

  假诺编写代码时,在把代码发送给编写翻译器前,要动用一些软件包改成输入的代码,就足以动用那么些命令,因为那代表编写翻译器报告的行号或文件名与公事中的行号或编辑的文件名不相称。

  #line 指令能够用来苏醒这种相配。也足以选拔语法#line default 把行号还原为私下认可的行号:

1 #line 164 "Core.cs" // We happen to know this is line 164 in the file
2 // Core.cs, before the intermediate
3 // package mangles it.
4 // later on
5 #line default // restores default line numbering

1. pragma

  #pragma 指令能够压制或还原内定的编写翻译警告。与命令行选项不一样,#pragma 指令能够在类或措施等第施行,对防止警告的内容和遏制的时间开展越来越精致的操纵。

  下边包车型地铁例子禁止“字段未采纳”警告,然后在编写翻译MyClass 类后还原该警告。

1 #pragma warning disable 169
2 public class MyClass
3 {
4 int neverUsedField;
5 }
6 #pragma warning restore 169

本文由澳门新萄京官方网站发布于www.8455.com,转载请注明出处:澳门新萄京官方网站:中的预编译指令介绍,预

关键词: