Chapter 9 configuration and Scheduling
In the previous chapter, you learned how to create a universal language runtime (CLR) component and how to use it in a simple test application. Although the CLR component is ready to be loaded, you should consider one of the following technologies:
. Conditional compilation
. Document comment
. Code version
9.1 Conditional compilation
Without the Conditional compilation function of the code, I cannot continue to work. Conditional compilation allows or includes code based on certain conditions; for example, generating an application
A debug version, DEMO version, or RELEASE version. Examples of code that may be included or executed are license generation
Code, screen saver, or any program you present.
In C #, there are two methods for Conditional compilation:
. Preprocessing usage
. Condition attributes
9.1.1 preprocessing usage
In C ++, the preprocessing steps are separated before the compiler starts to compile the code. In C #, preprocessing is simulated by the compiler itself-a pre-process without separation
Processing. It is just Conditional compilation.
Although the C # compiler does not support macros, it has the necessary functions to exclude and include code based on symbol-defined conditions. The following section describes how to count in C #
They are similar to those seen in C ++.
. Define symbols
. Exclude code by symbol
. Cause errors and warnings
9.1.1.1 definition symbols
You cannot use preprocessing with the C # compiler to create a "define flag: Symbol: Definition" macro. However, you can still define symbols. According to some symbols
Whether it is defined. Code can be excluded or included.
The first way to define symbols is to use the # define flag in the C # source file:
# Define DEBUG
In this way, the DEBUG symbol is defined and the scope is within the file defined by it. Note that you must define symbols before using other statements. For example, the following code
Segment is incorrect:
Using System;
# Define DEBUG
The compiler will mark the above Code as an error. You can also use the compiler to define symbols (for all files ):
Csc/define: DEBUG mysymbols. cs
To define multiple symbols using a compiler, separate them with semicolons:
Csc/define: RELEASE; DEMOVERSION mysymbols. cs
In the C # source file, the two symbols are defined in two lines: # define.
Sometimes, you may want to cancel a symbol in the source file (for example, the source file of a large project. You can use the # undef flag to cancel the definition:
# Undef DEBUG
# Define's "definition flag: Symbol: Definition" rule also applies to # undef: its scope is within its own defined file and should be placed in any statement such
Before the using statement.
This is all the knowledge about defining symbols with C # preprocessing and canceling definition symbols. The following sections describe how to use symbols to compile generation with conditional conditions:
.
9.1.1.2 include and exclude code based on symbols
The most important "if flag: Symbol: including code" method is to include and exclude code conditionally based on whether the symbol is defined. List 9.1 contains
The source code has appeared, but this time it is compiled with conditions based on the symbol.
Listing 9.1 uses # if flag to include code conditionally
1: using System;
2:
3: public class SquareSample
4 :{
5: public void CalcSquare (int nSideLength, out int nSquared)
6 :{
7: nSquared = nSideLength * nSideLength;
8 :}
9:
10: public int CalcSquare (int nSideLength)
11 :{
12: return nSideLength * nSideLength;
13 :}
14 :}
15:
16: class SquareApp
17 :{
18: public static void Main ()
19 :{
20: SquareSample sq = new SquareSample ();
21:
22: int nSquared = 0;
23:
24: # if CALC_W_OUT_PARAM
25: sq. CalcSquare (20, out nSquared );
26: # else
27: nSquared = sq. CalcSquare (15 );
28: # endif
29: Console. WriteLine (nSquared. ToString ());
30 :}
31 :}
Note that no symbols are defined in this source file. When compiling an application, define (or cancel definition) symbols:
Csc/define: CALC_W_OUT_PARAM square. cs
According to the definition of the "if flag: Symbol: including code" symbol, different CalcSquare is called. The simulated preprocessing mark used to evaluate the symbolic value is
# If, # else, And # endif. They produce the same effect as the if statement corresponding to C. You can also use the logical "and" (&), logical "or"
(& Brvbar;) and "no "(!). Their examples are shown in listing 9.2.
Listing 9.2 use # elif to create multiple branches in the # if flag
1: // # define DEBUG
2: # define RELEASE
3: # define DEMOVERSION
4:
5: # if DEBUG
6: # undef DEMOVERSION
7: # endif
8:
9: using System;
10:
11: class Demo
12 :{
13: public static void Main ()
14 :{
15: # if DEBUG
16: Console. WriteLine ("Debug version ");
17: # elif RELEASE &&! DEMOVERSION
18: Console. WriteLine ("Full release version ");
19: # else
20: Console. WriteLine ("Demo version ");
21: # endif
22 :}
23 :}
In this "if flag: Symbol: Contains code" example, all symbols are defined in the C # source file. Note the part added to line 1 # undef.
Since the DEMO version of the DEBUG code is not compiled (any choice), I am sure it will not be accidentally defined by some people, and it will be canceled when the DEBUG code is defined.
DEMO Version definition.
Then ~ Line 21: Pre-processing symbols are used to include various codes. Note # elif flag usage, which allows you to add multiple branches to the # if flag. The
The Code uses the logical operator "&" and non-operator "!". You may also use the logical operator "& brvbar;" and operations equal to and not equal
.
9.1.1.3 cause error and warning
Another possible "warning flag error flag" pre-processing flag is based on some symbols (or not at all, if you decide)
Error or warning. Their respective logos are # warning and # error, while listing 9.3 demonstrates how to use them in your code.
Listing 9.3 use the preprocessing flag to create compilation warnings and errors
1: # define DEBUG
2: # define RELEASE
3: # define DEMOVERSION
4:
5: # if DEMOVERSION &&! DEBUG
6: # warning You are building a demo version
7: # endif
8:
9: # if DEBUG & DEMOVERSION
10: # error You cannot build a debug demo version
11: # endif
12:
13: using System;
14:
15: class Demo
16 :{
17: public static void Main ()
18 :{
19: Console. WriteLine ("Demo application ");
20 :}
21 :}
In this example, When you generate a DEMO version that is not the DEBUG version, a compilation warning is issued (line 1 ~ 7th rows ). When you attempt to generate
In a debug demo version, an error occurs, which prevents the generation of executable files. Compare to the previous example that only cancels the definition of annoying symbols.
The Code tells you that the attempt to do the "warning mark error mark" is considered wrong. This must be a better solution.
9.1.1.4 condition attributes
The pre-processing of C ++ may be most often used to define macros. Macros can solve a function call when a program is generated, but cannot solve any of the tasks when another program is generated.
What is the problem. These examples include ASSERT and TRACE macros. When the DEBUG symbol is defined, they evaluate the function call. When a RELEASE version is generated
The value does not have any results.
When you know that macros are not supported, you may guess that the conditional function has vanished. Fortunately, I can report that this does not happen. You can use conditions
Attribute to include methods based on some defined symbols. :
[Conditional ("DEBUG")]
Public void SomeMethod (){}
This method is added to the executable file only when the symbol DEBUG is defined. And call it, just like
SomeMethod ();
When this method is not included, it is also declared by the compiler. The function is basically the same as using the C ++ conditional macro.
Before starting the example, I would like to point out that the condition method must have a return type of void and other return types are not allowed. However, you can pass
.
The example in listing 9.4 demonstrates how to use condition attributes to regenerate a TRACE macro with C ++. For simplicity, the results are directly output
Screen. You can also direct it to any place as needed, including a file.
Listing 9.4 how to implement conditional attributes
1: # define DEBUG
2:
3: using System;
4:
5: class Info
6 :{
7: [conditional ("DEBUG")]
8: public static void Trace (string strMessage)
9 :{