Outputting Code - Outputting Assignments
(Page 16 of 19 )
An assignment consists of two main parts: what you’re assigning to and the value you’re assigning. For example, to create the assignment iSum = 0, you’d use this:
Dim stmt2 As New CodeAssignStatement( _
New CodeVariableReferenceExpression("iSum"), _
New CodePrimitiveExpression(0))
entry.Statements.Add(stmt2)
You’ll often assign the results of a binary expression. A binary expression is an expression with two operands such as addition. It consists of three parts—the left operand, the operator, and the right operand. In the next example, the left operand of the binary expression is a previously created primitive expression, and the right operand is a newly created primitive expression. The code output by this fragment assigns the result of 42 + 23 to the iSum variable:
Dim stmt2 As New CodeAssignStatement( _
New CodeVariableReferenceExpression("iSum"), _
New CodeBinaryOperatorExpression(exp2, _
CodeBinaryOperatorType.Add, _
New CodePrimitiveExpression(23)))
entry.Statements.Add(stmt2)
So far, the CodeDOM samples make up about 40 lines of template code. What does the resulting code output look like? It can output code in any language with a CodeDOM provider. Because the generating code is in VB .NET, I’ll show the output in C#. After I removed the CodeDOM’s standard file opening comments, the output is as follows:
namespace CodeDOMTest {
using System;
public class Startup {
public static void Main() {
int iSum;
int iValue = 42;
System.IO.Stream stream;
string fileName = "Test.txt";
System.Console.WriteLine("Hello World");
iSum = 0;
iSum = (42 + 23);
}
}
}
NOTE: While the declaration was defined using the system type (System.Int32), it is output using the language specific keyword— int in C# or Integer in VB .NET. |
Wow! Not very impressive for 40 lines of code! But that’s life with the CodeDOM. In my experience, templates using the CodeDOM code contain at least three lines of complex code for every line generated.
Accessing Enums Enums in .NET are created as special classes derived from System.Enum, with each enum value declared as a read-only field. You access enum values by treating them as fields:
Dim enumValue As New CodeFieldReferenceExpression( _
New CodeTypeReferenceExpression( _
GetType(System.IO.FileMode)), _
"Create")
Often you’ll be referencing enums that aren’t part of the framework and aren’t available during generation. One way this can happen is to reference enums in the files you’re outputting. Because the class isn’t yet available, you’ll only be able to use a string to reference the enum. (See footnote 11.)
Footnote 11. The string approach always works, but it doesn’t offer strong typing benefits such as IntelliSense and compiler checks.
NOTE: To create a new enum in a class, create a new member with IsEnum set to True. Use the CodeFieldDeclaration to declare individual enum values. |
Creating Objects
Objects are generally created and assigned to a variable, either as part of the variable declaration or as a separate statement in the output file. The next code initializes the previously created stream variable by assigning to it to a new file stream:
Dim stmt3 As New CodeAssignStatement( _
New CodeVariableReferenceExpression("stream"), _
New CodeObjectCreateExpression( _
GetType(System.IO.FileStream), _
New CodeVariableReferenceExpression("fileName"), _
enumValue))
entry.Statements.Add(stmt3)
Declaring Array Variables You can declare arrays in two different ways. You can create a normal variable with an array type, and you can use an overload of the CodeTypeReference expression. The second parameter to CodeTypeReference is the rank of the array, which allows you to declare arrays with multiple dimensions:
' Declare an array
entry.Statements.Add( _
New CodeVariableDeclarationStatement( _
GetType(System.Int32()), "aInts"))
' Shows option for type declaration
entry.Statements.Add( _
New CodeVariableDeclarationStatement( _
New CodeTypeReference( _
New CodeTypeReference(GetType(System.Int32)), 1), _
"a2Ints"))
You might find examples using square brackets within strings to declare arrays, such as "System.Int32[]". Although understood by the CodeDOM, this isn’t the preferable way to declare arrays because you don’t get any strong typing benefits.
CAUTION: It’s often convenient to create variables in your CodeDOM code that hold references to expressions. Be cautious with these variables. You’ll often place one reference to an instance in the Statements collection (either directly or through another object) and retain another reference to the same instance. If you make changes, the previous entry in the Statements collection will also reflect those changes. You can create new objects, or you can clone the objects as you put them into the CodeDOM. This is just normal object-oriented behavior, but it’s different from the other two code generation mechanisms that output code as your template runs. The CodeDOM builds a complex object hierarchy and later outputs your code. If you forget this detail, you’ll make a mess of your output.
This chapter is from Code Generation in Microsoft .NET by Kathleen Dollard (Apress, 2004, ISBN: 1590591372). Check it out at your favorite bookstore today.
Buy this book now. |
Next: Creating Arrays >>
More .NET Articles
More By Apress Publishing