One might ask why the CodeDom does not generate a switch statement, and why it does not generate a while statement. Note that the CodeDom only cares about the code logic, not the syntax, which is used by the person writing the code. If a friend of the. Net "decompile" tool knows that you write a piece of code with a while statement, and then compile the build assembly, and then use the tool to "reverse" the code, you will find that you originally wrote the while statement, but out of the for statement, the truth is the same, "anti-compilation" The tool only cares about the execution logic of the code, not the syntax. Therefore, you naturally cannot use the CodeDom to generate the VAR keyword to declare a variable, you cannot generate a method represented by a LAMBDA expression, and you cannot generate a property definition syntax that has only get and set.
So, let's not confuse grammar with logic.
To introduce the branch first, the branch statement is like an if statement, represented by the Codeconditionstatement class, which requires three elements:
1, condition, used to determine whether the given expression is true.
2. The code executed when the condition is established.
3. The code executed when the condition is not established.
Here's an example of dividing a number by 2 and modulo (that is, taking the remainder), or even if the result is 0, otherwise odd. The code is as follows.
//Modulo OperationCodebinaryoperatorexpression Modexp =Newcodebinaryoperatorexpression (); Modexp. Operator=Codebinaryoperatortype.modulus; Modexp. Left=NewCodePrimitiveExpression (6); Modexp. Right=NewCodePrimitiveExpression (2); //Equality OperationsCodebinaryoperatorexpression Eqexp =Newcodebinaryoperatorexpression (); Eqexp. Operator=codebinaryoperatortype.identityequality; Eqexp. Left=Modexp; Eqexp. Right=NewCodePrimitiveExpression (0); //Branch StatementsCodeconditionstatement CODST =Newcodeconditionstatement (); //set the judging conditionCodst. Condition =Eqexp; //if it is trueCodst. Truestatements.add (NewCodeMethodInvokeExpression (NewCodemethodreferenceexpression (NewCodeTypeReferenceExpression (typeof(Console)), Nameof (Console.WriteLine)),NewCodePrimitiveExpression ("This is an even number. "))); //if the falseCodst. Falsestatements.add (NewCodeMethodInvokeExpression (NewCodemethodreferenceexpression (NewCodeTypeReferenceExpression (typeof(Console)), Nameof (Console.WriteLine)),NewCodePrimitiveExpression ("This is an odd number. "))); CodeDomProvider provider= Codedomprovider.createprovider ("CS"); Provider. Generatecodefromstatement (CODST, Console.Out,NULL);
The generated code is as follows:
Sometimes, the code only needs to determine the conditions and processing, and ignore the condition is not established, this time falsestatements can not add any statements. As in the example below.
//Defining VariablesCodevariabledeclarationstatement Varst =NewCodevariabledeclarationstatement (typeof(string),"Str",NewCodePrimitiveExpression ("I-s-h-e-j-d-u")); //accessing the properties of a variable instanceCodePropertyReferenceExpression Prpref =NewCodePropertyReferenceExpression (NewCodevariablereferenceexpression (Varst. Name), nameof (string. Length)); //An expression that generates a judging conditionCodebinaryoperatorexpression Codexp =Newcodebinaryoperatorexpression (); Codexp. Operator=Codebinaryoperatortype.greaterthan; Codexp. Left=Prpref; Codexp. Right=NewCodePrimitiveExpression (5); //Branch StatementsCodeconditionstatement codstatement =Newcodeconditionstatement (); Codstatement. Condition=Codexp; //when conditions are establishedCodeMethodInvokeExpression Invmeth =NewCodeMethodInvokeExpression (); Invmeth. Method=NewCodemethodreferenceexpression (NewCodeTypeReferenceExpression (typeof(Console)), Nameof (Console.WriteLine)); Invmeth. Parameters.Add (NewCodePrimitiveExpression ("string length is out of range. ")); Codstatement. Truestatements.add (Invmeth); CodeDomProvider PRD= Codedomprovider.createprovider ("CS"); Prd. Generatecodefromstatement (Varst, Console.Out,NULL); Prd. Generatecodefromstatement (Codstatement, Console.Out,NULL);
This example generates code that declares a string type variable and initializes it. It then determines its length and performs the output conditionally. The generated code is as follows.
===========================================
The generation of a looping statement is not difficult, it is generated by the Codeiterationstatement class, which is structured like a for statement and consists of elements:
1, the initial value of the cyclic condition.
2, judge whether to perform the conditions of the cycle.
3. Changes to the cyclic conditions.
The following example generates a standard for loop.
Codeiterationstatement its =Newcodeiterationstatement (); //Initialize ConditionIts. Initstatement =NewCodevariabledeclarationstatement (typeof(int),"I",NewCodePrimitiveExpression (0)); //condition CheckIts. testexpression =NewCodebinaryoperatorexpression (NewCodevariablereferenceexpression ("I"), Codebinaryoperatortype.lessthan,NewCodePrimitiveExpression (9)); //changes to conditions after each round of cyclesIts. Incrementstatement =NewCodeAssignStatement (NewCodevariablereferenceexpression ("I"),NewCodebinaryoperatorexpression (NewCodevariablereferenceexpression ("I"), Codebinaryoperatortype.add,NewCodePrimitiveExpression (2))); //Loop BodyIts. Statements.add (NewCodeCommentStatement ("Loop Body Code")); CodeDomProvider PRD= Codedomprovider.createprovider ("vb"); Prd. Generatecodefromstatement (ITS, console.out,NULL);
Initializes a variable I, provided it is less than 9 o'clock cycles, and the condition is added 2 after each loop.
This time you will find that the generated VB code is a while loop.
The generated C # code is a for loop.
You don't care what it is. syntax format, as long as the logic on the line, this is generated code, not write code, do not suffer from obsessive-compulsive disorder.
Do you want to have a dead loop, in fact, the dead loop as long as let testexpression forever is true, and, Incrementstatement will not change the value of the condition is OK. Like this.
Codeiterationstatement ITSMT =Newcodeiterationstatement (); Itsmt. Initstatement=NewCodevariabledeclarationstatement (typeof(BOOL),"N",NewCodePrimitiveExpression (true)); Itsmt. Testexpression=NewCodevariablereferenceexpression ("N"); Itsmt. Incrementstatement=NewCodeAssignStatement (NewCodevariablereferenceexpression ("N"),NewCodePrimitiveExpression (true)); Itsmt. Statements.add (NewCodeCommentStatement ("Infinite Death ...")); CodeDomProvider PRD= Codedomprovider.createprovider ("CS"); Prd. Generatecodefromstatement (ITSMT, Console.Out,NULL);
Initialize the variable to true, and let it be true after each round of the loop. The generated code is as follows:
In fact, it can be a little simpler.
Codeiterationstatement ITSMT =Newcodeiterationstatement (); Itsmt. Initstatement=NewCodeSnippetStatement (""); Itsmt. Testexpression=NewCodePrimitiveExpression (true); Itsmt. Incrementstatement=NewCodeSnippetStatement (""); Itsmt. Statements.add (NewCodeCommentStatement ("Infinite Death ...")); CodeDomProvider PRD= Codedomprovider.createprovider ("CS"); Prd. Generatecodefromstatement (ITSMT, Console.Out,NULL);
Old weeks in the previous introduction, the CodeSnippetStatement class can generate code with literal text, here we put literal text with null characters, will generate blank statement.
So, the generated C # code is this:
The generated VB code is this:
The generated C + + code is this:
Well, the generation of logical code for branching and looping is here, and in the next article, let's start talking about compiling the code.
". Net deep Breathing" detail CodeDom (8): Branching and looping