HOW TO:使用 CodeDOM 建立類別
下列程序說明如何建立及編譯會產生一個類別的 CodeDOM 圖形,此類別包含兩個欄位、三個屬性、一個方法、一個建構函式 (Constructor) 和一個進入點 (Entry Point)。
建立將使用 CodeDOM 程式碼產生類別之原始程式碼的主控台應用程式 (Console Application)。
在此範例中,產生的類別名為 Sample,而且產生的程式碼是一個名為 CodeDOMCreatedClass 的類別,位於名為 SampleCode 的檔案中。
在產生的類別中,初始化 CodeDOM 圖形及使用 CodeDOM 方法來定義產生之類別的成員、建構函式和進入點 (Main 方法)。
在此範例中,產生的類別有兩個欄位、三個屬性、一個建構函式、一個方法和一個 Main 方法。
在產生的類別中,建立特定語言的程式碼提供者,並呼叫其 GenerateCodeFromCompileUnit 方法,從圖形產生程式碼。
編譯並執行應用程式來產生程式碼。
在此範例中,產生的程式碼位於名為 SampleCode 的檔案中。 請編譯並執行該程式碼,以查看範例輸出。
若要建立將執行 CodeDOM 程式碼的應用程式。
建立一個包含 CodeDOM 程式碼的主控台應用程式類別。 定義此類別中用於參考組件 (CodeCompileUnit) 和類別 (CodeTypeDeclaration) 的全域欄位、指定產生之原始程式檔 (Source File) 的名稱,並宣告 Main 方法。
Imports System Imports System.Reflection Imports System.IO Imports System.CodeDom Imports System.CodeDom.Compiler Imports Microsoft.CSharp Class Sample Private targetUnit As CodeCompileUnit Private targetClass As CodeTypeDeclaration Private Const outputFileName As String = "SampleCode.cs" Shared Sub Main(ByVal args() As String) End Sub 'Main End Class 'Sample
using System; using System.Reflection; using System.IO; using System.CodeDom; using System.CodeDom.Compiler; using Microsoft.CSharp; namespace SampleCodeDom { class Sample { CodeCompileUnit targetUnit; CodeTypeDeclaration targetClass; private const string outputFileName = "SampleCode.cs"; static void Main(string[] args) { } } }
若要初始化 CodeDOM 圖形
在主控台應用程式類別的建構函式中,初始化組件和類別,並對 CodeDOM 圖形加入適當的宣告。
Public Sub New() targetUnit = New CodeCompileUnit() Dim samples As New CodeNamespace("CodeDOMSample") samples.Imports.Add(New CodeNamespaceImport("System")) targetClass = New CodeTypeDeclaration("CodeDOMCreatedClass") targetClass.IsClass = True targetClass.TypeAttributes = _ TypeAttributes.Public Or TypeAttributes.Sealed samples.Types.Add(targetClass) targetUnit.Namespaces.Add(samples) End Sub 'New
public Sample() { targetUnit = new CodeCompileUnit(); CodeNamespace samples = new CodeNamespace("CodeDOMSample"); samples.Imports.Add(new CodeNamespaceImport("System")); targetClass = new CodeTypeDeclaration("CodeDOMCreatedClass"); targetClass.IsClass = true; targetClass.TypeAttributes = TypeAttributes.Public | TypeAttributes.Sealed; samples.Types.Add(targetClass); targetUnit.Namespaces.Add(samples); }
若要將成員加入至 CodeDOM 圖形中
將 CodeMemberField 物件加入至此類別的 Members 屬性中,藉此將欄位加入至 CodeDOM 圖形中。
Public Sub AddFields() ' Declare the widthValue field. Dim widthValueField As New CodeMemberField() widthValueField.Attributes = MemberAttributes.Private widthValueField.Name = "widthValue" widthValueField.Type = _ New CodeTypeReference(GetType(System.Double)) widthValueField.Comments.Add(New CodeCommentStatement( _ "The width of the object.")) targetClass.Members.Add(widthValueField) ' Declare the heightValue field Dim heightValueField As New CodeMemberField() heightValueField.Attributes = MemberAttributes.Private heightValueField.Name = "heightValue" heightValueField.Type = _ New CodeTypeReference(GetType(System.Double)) heightValueField.Comments.Add(New CodeCommentStatement( _ "The height of the object.")) targetClass.Members.Add(heightValueField) End Sub 'AddFields
public void AddFields() { // Declare the widthValue field. CodeMemberField widthValueField = new CodeMemberField(); widthValueField.Attributes = MemberAttributes.Private; widthValueField.Name = "widthValue"; widthValueField.Type = new CodeTypeReference(typeof(System.Double)); widthValueField.Comments.Add(new CodeCommentStatement( "The width of the object.")); targetClass.Members.Add(widthValueField); // Declare the heightValue field CodeMemberField heightValueField = new CodeMemberField(); heightValueField.Attributes = MemberAttributes.Private; heightValueField.Name = "heightValue"; heightValueField.Type = new CodeTypeReference(typeof(System.Double)); heightValueField.Comments.Add(new CodeCommentStatement( "The height of the object.")); targetClass.Members.Add(heightValueField); }
將 CodeMemberProperty 物件加入至此類別的 Members 屬性中,藉此將屬性加入至 CodeDOM 圖形中。
Public Sub AddProperties() ' Declare the read only Width property. Dim widthProperty As New CodeMemberProperty() widthProperty.Attributes = _ MemberAttributes.Public Or MemberAttributes.Final widthProperty.Name = "Width" widthProperty.HasGet = True widthProperty.Type = New CodeTypeReference(GetType(System.Double)) widthProperty.Comments.Add(New CodeCommentStatement( _ "The width property for the object.")) widthProperty.GetStatements.Add(New CodeMethodReturnStatement( _ New CodeFieldReferenceExpression( _ New CodeThisReferenceExpression(), "widthValue"))) targetClass.Members.Add(widthProperty) ' Declare the read-only Height property. Dim heightProperty As New CodeMemberProperty() heightProperty.Attributes = _ MemberAttributes.Public Or MemberAttributes.Final heightProperty.Name = "Height" heightProperty.HasGet = True heightProperty.Type = New CodeTypeReference(GetType(System.Double)) heightProperty.Comments.Add(New CodeCommentStatement( _ "The Height property for the object.")) heightProperty.GetStatements.Add(New CodeMethodReturnStatement( _ New CodeFieldReferenceExpression( _ New CodeThisReferenceExpression(), "heightValue"))) targetClass.Members.Add(heightProperty) ' Declare the read only Area property. Dim areaProperty As New CodeMemberProperty() areaProperty.Attributes = _ MemberAttributes.Public Or MemberAttributes.Final areaProperty.Name = "Area" areaProperty.HasGet = True areaProperty.Type = New CodeTypeReference(GetType(System.Double)) areaProperty.Comments.Add(New CodeCommentStatement( _ "The Area property for the object.")) ' Create an expression to calculate the area for the get accessor ' of the Area property. Dim areaExpression As New CodeBinaryOperatorExpression( _ New CodeFieldReferenceExpression( _ New CodeThisReferenceExpression(), "widthValue"), _ CodeBinaryOperatorType.Multiply, _ New CodeFieldReferenceExpression( _ New CodeThisReferenceExpression(), "heightValue")) areaProperty.GetStatements.Add( _ New CodeMethodReturnStatement(areaExpression)) targetClass.Members.Add(areaProperty) End Sub 'AddProperties
public void AddProperties() { // Declare the read-only Width property. CodeMemberProperty widthProperty = new CodeMemberProperty(); widthProperty.Attributes = MemberAttributes.Public | MemberAttributes.Final; widthProperty.Name = "Width"; widthProperty.HasGet = true; widthProperty.Type = new CodeTypeReference(typeof(System.Double)); widthProperty.Comments.Add(new CodeCommentStatement( "The Width property for the object.")); widthProperty.GetStatements.Add(new CodeMethodReturnStatement( new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), "widthValue"))); targetClass.Members.Add(widthProperty); // Declare the read-only Height property. CodeMemberProperty heightProperty = new CodeMemberProperty(); heightProperty.Attributes = MemberAttributes.Public | MemberAttributes.Final; heightProperty.Name = "Height"; heightProperty.HasGet = true; heightProperty.Type = new CodeTypeReference(typeof(System.Double)); heightProperty.Comments.Add(new CodeCommentStatement( "The Height property for the object.")); heightProperty.GetStatements.Add(new CodeMethodReturnStatement( new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), "heightValue"))); targetClass.Members.Add(heightProperty); // Declare the read only Area property. CodeMemberProperty areaProperty = new CodeMemberProperty(); areaProperty.Attributes = MemberAttributes.Public | MemberAttributes.Final; areaProperty.Name = "Area"; areaProperty.HasGet = true; areaProperty.Type = new CodeTypeReference(typeof(System.Double)); areaProperty.Comments.Add(new CodeCommentStatement( "The Area property for the object.")); // Create an expression to calculate the area for the get accessor // of the Area property. CodeBinaryOperatorExpression areaExpression = new CodeBinaryOperatorExpression( new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), "widthValue"), CodeBinaryOperatorType.Multiply, new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), "heightValue")); areaProperty.GetStatements.Add( new CodeMethodReturnStatement(areaExpression)); targetClass.Members.Add(areaProperty); }
將 CodeMemberMethod 物件加入至此類別的 Members 屬性中,藉此將方法加入至 CodeDOM 圖形中。
Public Sub AddMethod() ' Declaring a ToString method. Dim toStringMethod As New CodeMemberMethod() toStringMethod.Attributes = _ MemberAttributes.Public Or MemberAttributes.Override toStringMethod.Name = "ToString" toStringMethod.ReturnType = _ New CodeTypeReference(GetType(System.String)) Dim widthReference As New CodeFieldReferenceExpression( _ New CodeThisReferenceExpression(), "Width") Dim heightReference As New CodeFieldReferenceExpression( _ New CodeThisReferenceExpression(), "Height") Dim areaReference As New CodeFieldReferenceExpression( _ New CodeThisReferenceExpression(), "Area") ' Declaring a return statement for method ToString. Dim returnStatement As New CodeMethodReturnStatement() ' This statement returns a string representation of the width, ' height, and area. Dim formattedOutput As String = "The object:" & Environment.NewLine _ & " width = {0}," & Environment.NewLine & " height = {1}," _ & Environment.NewLine & " area = {2}" returnStatement.Expression = New CodeMethodInvokeExpression( _ New CodeTypeReferenceExpression("System.String"), "Format", _ New CodePrimitiveExpression(formattedOutput), widthReference, _ heightReference, areaReference) toStringMethod.Statements.Add(returnStatement) targetClass.Members.Add(toStringMethod) End Sub 'AddMethod
public void AddMethod() { // Declaring a ToString method CodeMemberMethod toStringMethod = new CodeMemberMethod(); toStringMethod.Attributes = MemberAttributes.Public | MemberAttributes.Override; toStringMethod.Name = "ToString"; toStringMethod.ReturnType = new CodeTypeReference(typeof(System.String)); CodeFieldReferenceExpression widthReference = new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), "Width"); CodeFieldReferenceExpression heightReference = new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), "Height"); CodeFieldReferenceExpression areaReference = new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), "Area"); // Declaring a return statement for method ToString. CodeMethodReturnStatement returnStatement = new CodeMethodReturnStatement(); // This statement returns a string representation of the width, // height, and area. string formattedOutput = "The object:" + Environment.NewLine + " width = {0}," + Environment.NewLine + " height = {1}," + Environment.NewLine + " area = {2}"; returnStatement.Expression = new CodeMethodInvokeExpression( new CodeTypeReferenceExpression("System.String"), "Format", new CodePrimitiveExpression(formattedOutput), widthReference, heightReference, areaReference); toStringMethod.Statements.Add(returnStatement); targetClass.Members.Add(toStringMethod); }
將 CodeConstructor 物件加入至此類別的 Members 屬性中,藉此將建構函式加入至 CodeDOM 圖形中。
Public Sub AddConstructor() ' Declare the constructor Dim constructor As New CodeConstructor() constructor.Attributes = _ MemberAttributes.Public Or MemberAttributes.Final ' Add parameters. constructor.Parameters.Add( _ New CodeParameterDeclarationExpression( _ GetType(System.Double), "width")) constructor.Parameters.Add( _ New CodeParameterDeclarationExpression( _ GetType(System.Double), "height")) ' Add field initialization logic Dim widthReference As New CodeFieldReferenceExpression( _ New CodeThisReferenceExpression(), "widthValue") constructor.Statements.Add(New CodeAssignStatement( _ widthReference, New CodeArgumentReferenceExpression("width"))) Dim heightReference As New CodeFieldReferenceExpression( _ New CodeThisReferenceExpression(), "heightValue") constructor.Statements.Add( _ New CodeAssignStatement(heightReference, _ New CodeArgumentReferenceExpression("height"))) targetClass.Members.Add(constructor) End Sub 'AddConstructor
public void AddConstructor() { // Declare the constructor CodeConstructor constructor = new CodeConstructor(); constructor.Attributes = MemberAttributes.Public | MemberAttributes.Final; // Add parameters. constructor.Parameters.Add(new CodeParameterDeclarationExpression( typeof(System.Double), "width")); constructor.Parameters.Add(new CodeParameterDeclarationExpression( typeof(System.Double), "height")); // Add field initialization logic CodeFieldReferenceExpression widthReference = new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), "widthValue"); constructor.Statements.Add(new CodeAssignStatement(widthReference, new CodeArgumentReferenceExpression("width"))); CodeFieldReferenceExpression heightReference = new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), "heightValue"); constructor.Statements.Add(new CodeAssignStatement(heightReference, new CodeArgumentReferenceExpression("height"))); targetClass.Members.Add(constructor); }
將 CodeEntryPointMethod 物件加入至此類別的 Members 屬性中,藉此將進入點加入至 CodeDOM 圖形中。
Public Sub AddEntryPoint() Dim start As New CodeEntryPointMethod() Dim objectCreate As New CodeObjectCreateExpression( _ New CodeTypeReference("CodeDOMCreatedClass"), _ New CodePrimitiveExpression(5.3), _ New CodePrimitiveExpression(6.9)) ' Add the statement: ' "CodeDOMCreatedClass testClass = _ ' new CodeDOMCreatedClass(5.3, 6.9);" start.Statements.Add(New CodeVariableDeclarationStatement( _ New CodeTypeReference("CodeDOMCreatedClass"), _ "testClass", objectCreate)) ' Creat the expression: ' "testClass.ToString()" Dim toStringInvoke As New CodeMethodInvokeExpression( _ New CodeVariableReferenceExpression("testClass"), "ToString") ' Add a System.Console.WriteLine statement with the previous ' expression as a parameter. start.Statements.Add(New CodeMethodInvokeExpression( _ New CodeTypeReferenceExpression("System.Console"), _ "WriteLine", toStringInvoke)) targetClass.Members.Add(start) End Sub 'AddEntryPoint
public void AddEntryPoint() { CodeEntryPointMethod start = new CodeEntryPointMethod(); CodeObjectCreateExpression objectCreate = new CodeObjectCreateExpression( new CodeTypeReference("CodeDOMCreatedClass"), new CodePrimitiveExpression(5.3), new CodePrimitiveExpression(6.9)); // Add the statement: // "CodeDOMCreatedClass testClass = // new CodeDOMCreatedClass(5.3, 6.9);" start.Statements.Add(new CodeVariableDeclarationStatement( new CodeTypeReference("CodeDOMCreatedClass"), "testClass", objectCreate)); // Creat the expression: // "testClass.ToString()" CodeMethodInvokeExpression toStringInvoke = new CodeMethodInvokeExpression( new CodeVariableReferenceExpression("testClass"), "ToString"); // Add a System.Console.WriteLine statement with the previous // expression as a parameter. start.Statements.Add(new CodeMethodInvokeExpression( new CodeTypeReferenceExpression("System.Console"), "WriteLine", toStringInvoke)); targetClass.Members.Add(start); }
若要從 CodeDOM 圖形產生程式碼
藉由呼叫 GenerateCodeFromCompileUnit 方法來從 CodeDOM 圖形產生原始程式碼。
Public Sub GenerateVBCode(ByVal fileName As String) Dim provider As CodeDomProvider provider = CodeDomProvider.CreateProvider("VisualBasic") Dim options As New CodeGeneratorOptions() Dim sourceWriter As New StreamWriter(fileName) Try provider.GenerateCodeFromCompileUnit( _ targetUnit, sourceWriter, options) Finally sourceWriter.Dispose() End Try End Sub 'GenerateVBCode
public void GenerateCSharpCode(string fileName) { CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp"); CodeGeneratorOptions options = new CodeGeneratorOptions(); options.BracingStyle = "C"; using (StreamWriter sourceWriter = new StreamWriter(fileName)) { provider.GenerateCodeFromCompileUnit( targetUnit, sourceWriter, options); } }
若要建立圖形及產生程式碼
將先前步驟中建立的方法加入至第一個步驟所定義的 Main 方法。
Shared Sub Main() Dim sample As New Sample() sample.AddFields() sample.AddProperties() sample.AddMethod() sample.AddConstructor() sample.AddEntryPoint() sample.GenerateVBCode(outputFileName) End Sub 'Main End Class 'Sample
static void Main() { Sample sample = new Sample(); sample.AddFields(); sample.AddProperties(); sample.AddMethod(); sample.AddConstructor(); sample.AddEntryPoint(); sample.GenerateCSharpCode(outputFileName); }
編譯並執行產生的類別。
範例
下列程式碼範例顯示從先前步驟產生的程式碼。
Imports System
Imports System.Reflection
Imports System.IO
Imports System.CodeDom
Imports System.CodeDom.Compiler
Imports Microsoft.VisualBasic
' This code example creates a graph using a CodeCompileUnit and
' generates source code for the graph using the VBCodeProvider.
Class Sample
' Define the compile unit to use for code generation.
Private targetUnit As CodeCompileUnit
' The only class in the compile unit. This class contains 2 fields,
' 3 properties, a constructor, an entry point, and 1 simple method.
Private targetClass As CodeTypeDeclaration
' The name of the file to contain the source code.
Private Const outputFileName As String = "SampleCode.vb"
' Define the class.
Public Sub New()
targetUnit = New CodeCompileUnit()
Dim samples As New CodeNamespace("CodeDOMSample")
samples.Imports.Add(New CodeNamespaceImport("System"))
targetClass = New CodeTypeDeclaration("CodeDOMCreatedClass")
targetClass.IsClass = True
targetClass.TypeAttributes = _
TypeAttributes.Public Or TypeAttributes.Sealed
samples.Types.Add(targetClass)
targetUnit.Namespaces.Add(samples)
End Sub 'New
' Adds two fields to the class.
Public Sub AddFields()
' Declare the widthValue field.
Dim widthValueField As New CodeMemberField()
widthValueField.Attributes = MemberAttributes.Private
widthValueField.Name = "widthValue"
widthValueField.Type = _
New CodeTypeReference(GetType(System.Double))
widthValueField.Comments.Add(New CodeCommentStatement( _
"The width of the object."))
targetClass.Members.Add(widthValueField)
' Declare the heightValue field
Dim heightValueField As New CodeMemberField()
heightValueField.Attributes = MemberAttributes.Private
heightValueField.Name = "heightValue"
heightValueField.Type = _
New CodeTypeReference(GetType(System.Double))
heightValueField.Comments.Add(New CodeCommentStatement( _
"The height of the object."))
targetClass.Members.Add(heightValueField)
End Sub 'AddFields
' Add three properties to the class.
Public Sub AddProperties()
' Declare the read only Width property.
Dim widthProperty As New CodeMemberProperty()
widthProperty.Attributes = _
MemberAttributes.Public Or MemberAttributes.Final
widthProperty.Name = "Width"
widthProperty.HasGet = True
widthProperty.Type = New CodeTypeReference(GetType(System.Double))
widthProperty.Comments.Add(New CodeCommentStatement( _
"The width property for the object."))
widthProperty.GetStatements.Add(New CodeMethodReturnStatement( _
New CodeFieldReferenceExpression( _
New CodeThisReferenceExpression(), "widthValue")))
targetClass.Members.Add(widthProperty)
' Declare the read-only Height property.
Dim heightProperty As New CodeMemberProperty()
heightProperty.Attributes = _
MemberAttributes.Public Or MemberAttributes.Final
heightProperty.Name = "Height"
heightProperty.HasGet = True
heightProperty.Type = New CodeTypeReference(GetType(System.Double))
heightProperty.Comments.Add(New CodeCommentStatement( _
"The Height property for the object."))
heightProperty.GetStatements.Add(New CodeMethodReturnStatement( _
New CodeFieldReferenceExpression( _
New CodeThisReferenceExpression(), "heightValue")))
targetClass.Members.Add(heightProperty)
' Declare the read only Area property.
Dim areaProperty As New CodeMemberProperty()
areaProperty.Attributes = _
MemberAttributes.Public Or MemberAttributes.Final
areaProperty.Name = "Area"
areaProperty.HasGet = True
areaProperty.Type = New CodeTypeReference(GetType(System.Double))
areaProperty.Comments.Add(New CodeCommentStatement( _
"The Area property for the object."))
' Create an expression to calculate the area for the get accessor
' of the Area property.
Dim areaExpression As New CodeBinaryOperatorExpression( _
New CodeFieldReferenceExpression( _
New CodeThisReferenceExpression(), "widthValue"), _
CodeBinaryOperatorType.Multiply, _
New CodeFieldReferenceExpression( _
New CodeThisReferenceExpression(), "heightValue"))
areaProperty.GetStatements.Add( _
New CodeMethodReturnStatement(areaExpression))
targetClass.Members.Add(areaProperty)
End Sub 'AddProperties
' Adds a method to the class. This method multiplies values stored
' in both fields.
Public Sub AddMethod()
' Declaring a ToString method.
Dim toStringMethod As New CodeMemberMethod()
toStringMethod.Attributes = _
MemberAttributes.Public Or MemberAttributes.Override
toStringMethod.Name = "ToString"
toStringMethod.ReturnType = _
New CodeTypeReference(GetType(System.String))
Dim widthReference As New CodeFieldReferenceExpression( _
New CodeThisReferenceExpression(), "Width")
Dim heightReference As New CodeFieldReferenceExpression( _
New CodeThisReferenceExpression(), "Height")
Dim areaReference As New CodeFieldReferenceExpression( _
New CodeThisReferenceExpression(), "Area")
' Declaring a return statement for method ToString.
Dim returnStatement As New CodeMethodReturnStatement()
' This statement returns a string representation of the width,
' height, and area.
Dim formattedOutput As String = "The object:" & Environment.NewLine _
& " width = {0}," & Environment.NewLine & " height = {1}," _
& Environment.NewLine & " area = {2}"
returnStatement.Expression = New CodeMethodInvokeExpression( _
New CodeTypeReferenceExpression("System.String"), "Format", _
New CodePrimitiveExpression(formattedOutput), widthReference, _
heightReference, areaReference)
toStringMethod.Statements.Add(returnStatement)
targetClass.Members.Add(toStringMethod)
End Sub 'AddMethod
' Add a constructor to the class.
Public Sub AddConstructor()
' Declare the constructor
Dim constructor As New CodeConstructor()
constructor.Attributes = _
MemberAttributes.Public Or MemberAttributes.Final
' Add parameters.
constructor.Parameters.Add( _
New CodeParameterDeclarationExpression( _
GetType(System.Double), "width"))
constructor.Parameters.Add( _
New CodeParameterDeclarationExpression( _
GetType(System.Double), "height"))
' Add field initialization logic
Dim widthReference As New CodeFieldReferenceExpression( _
New CodeThisReferenceExpression(), "widthValue")
constructor.Statements.Add(New CodeAssignStatement( _
widthReference, New CodeArgumentReferenceExpression("width")))
Dim heightReference As New CodeFieldReferenceExpression( _
New CodeThisReferenceExpression(), "heightValue")
constructor.Statements.Add( _
New CodeAssignStatement(heightReference, _
New CodeArgumentReferenceExpression("height")))
targetClass.Members.Add(constructor)
End Sub 'AddConstructor
' Add an entry point to the class.
Public Sub AddEntryPoint()
Dim start As New CodeEntryPointMethod()
Dim objectCreate As New CodeObjectCreateExpression( _
New CodeTypeReference("CodeDOMCreatedClass"), _
New CodePrimitiveExpression(5.3), _
New CodePrimitiveExpression(6.9))
' Add the statement:
' "CodeDOMCreatedClass testClass = _
' new CodeDOMCreatedClass(5.3, 6.9);"
start.Statements.Add(New CodeVariableDeclarationStatement( _
New CodeTypeReference("CodeDOMCreatedClass"), _
"testClass", objectCreate))
' Creat the expression:
' "testClass.ToString()"
Dim toStringInvoke As New CodeMethodInvokeExpression( _
New CodeVariableReferenceExpression("testClass"), "ToString")
' Add a System.Console.WriteLine statement with the previous
' expression as a parameter.
start.Statements.Add(New CodeMethodInvokeExpression( _
New CodeTypeReferenceExpression("System.Console"), _
"WriteLine", toStringInvoke))
targetClass.Members.Add(start)
End Sub 'AddEntryPoint
' Generate Visual Basic source code from the compile unit.
Public Sub GenerateVBCode(ByVal fileName As String)
Dim provider As CodeDomProvider
provider = CodeDomProvider.CreateProvider("VisualBasic")
Dim options As New CodeGeneratorOptions()
Dim sourceWriter As New StreamWriter(fileName)
Try
provider.GenerateCodeFromCompileUnit( _
targetUnit, sourceWriter, options)
Finally
sourceWriter.Dispose()
End Try
End Sub 'GenerateVBCode
' Create the CodeDOM graph and generate the code.
Shared Sub Main()
Dim sample As New Sample()
sample.AddFields()
sample.AddProperties()
sample.AddMethod()
sample.AddConstructor()
sample.AddEntryPoint()
sample.GenerateVBCode(outputFileName)
End Sub 'Main
End Class 'Sample
using System;
using System.Reflection;
using System.IO;
using System.CodeDom;
using System.CodeDom.Compiler;
using Microsoft.CSharp;
namespace SampleCodeDom
{
/// <summary>
/// This code example creates a graph using a CodeCompileUnit and
/// generates source code for the graph using the CSharpCodeProvider.
/// </summary>
class Sample
{
/// <summary>
/// Define the compile unit to use for code generation.
/// </summary>
CodeCompileUnit targetUnit;
/// <summary>
/// The only class in the compile unit. This class contains 2 fields,
/// 3 properties, a constructor, an entry point, and 1 simple method.
/// </summary>
CodeTypeDeclaration targetClass;
/// <summary>
/// The name of the file to contain the source code.
/// </summary>
private const string outputFileName = "SampleCode.cs";
/// <summary>
/// Define the class.
/// </summary>
public Sample()
{
targetUnit = new CodeCompileUnit();
CodeNamespace samples = new CodeNamespace("CodeDOMSample");
samples.Imports.Add(new CodeNamespaceImport("System"));
targetClass = new CodeTypeDeclaration("CodeDOMCreatedClass");
targetClass.IsClass = true;
targetClass.TypeAttributes =
TypeAttributes.Public | TypeAttributes.Sealed;
samples.Types.Add(targetClass);
targetUnit.Namespaces.Add(samples);
}
/// <summary>
/// Adds two fields to the class.
/// </summary>
public void AddFields()
{
// Declare the widthValue field.
CodeMemberField widthValueField = new CodeMemberField();
widthValueField.Attributes = MemberAttributes.Private;
widthValueField.Name = "widthValue";
widthValueField.Type = new CodeTypeReference(typeof(System.Double));
widthValueField.Comments.Add(new CodeCommentStatement(
"The width of the object."));
targetClass.Members.Add(widthValueField);
// Declare the heightValue field
CodeMemberField heightValueField = new CodeMemberField();
heightValueField.Attributes = MemberAttributes.Private;
heightValueField.Name = "heightValue";
heightValueField.Type =
new CodeTypeReference(typeof(System.Double));
heightValueField.Comments.Add(new CodeCommentStatement(
"The height of the object."));
targetClass.Members.Add(heightValueField);
}
/// <summary>
/// Add three properties to the class.
/// </summary>
public void AddProperties()
{
// Declare the read-only Width property.
CodeMemberProperty widthProperty = new CodeMemberProperty();
widthProperty.Attributes =
MemberAttributes.Public | MemberAttributes.Final;
widthProperty.Name = "Width";
widthProperty.HasGet = true;
widthProperty.Type = new CodeTypeReference(typeof(System.Double));
widthProperty.Comments.Add(new CodeCommentStatement(
"The Width property for the object."));
widthProperty.GetStatements.Add(new CodeMethodReturnStatement(
new CodeFieldReferenceExpression(
new CodeThisReferenceExpression(), "widthValue")));
targetClass.Members.Add(widthProperty);
// Declare the read-only Height property.
CodeMemberProperty heightProperty = new CodeMemberProperty();
heightProperty.Attributes =
MemberAttributes.Public | MemberAttributes.Final;
heightProperty.Name = "Height";
heightProperty.HasGet = true;
heightProperty.Type = new CodeTypeReference(typeof(System.Double));
heightProperty.Comments.Add(new CodeCommentStatement(
"The Height property for the object."));
heightProperty.GetStatements.Add(new CodeMethodReturnStatement(
new CodeFieldReferenceExpression(
new CodeThisReferenceExpression(), "heightValue")));
targetClass.Members.Add(heightProperty);
// Declare the read only Area property.
CodeMemberProperty areaProperty = new CodeMemberProperty();
areaProperty.Attributes =
MemberAttributes.Public | MemberAttributes.Final;
areaProperty.Name = "Area";
areaProperty.HasGet = true;
areaProperty.Type = new CodeTypeReference(typeof(System.Double));
areaProperty.Comments.Add(new CodeCommentStatement(
"The Area property for the object."));
// Create an expression to calculate the area for the get accessor
// of the Area property.
CodeBinaryOperatorExpression areaExpression =
new CodeBinaryOperatorExpression(
new CodeFieldReferenceExpression(
new CodeThisReferenceExpression(), "widthValue"),
CodeBinaryOperatorType.Multiply,
new CodeFieldReferenceExpression(
new CodeThisReferenceExpression(), "heightValue"));
areaProperty.GetStatements.Add(
new CodeMethodReturnStatement(areaExpression));
targetClass.Members.Add(areaProperty);
}
/// <summary>
/// Adds a method to the class. This method multiplies values stored
/// in both fields.
/// </summary>
public void AddMethod()
{
// Declaring a ToString method
CodeMemberMethod toStringMethod = new CodeMemberMethod();
toStringMethod.Attributes =
MemberAttributes.Public | MemberAttributes.Override;
toStringMethod.Name = "ToString";
toStringMethod.ReturnType =
new CodeTypeReference(typeof(System.String));
CodeFieldReferenceExpression widthReference =
new CodeFieldReferenceExpression(
new CodeThisReferenceExpression(), "Width");
CodeFieldReferenceExpression heightReference =
new CodeFieldReferenceExpression(
new CodeThisReferenceExpression(), "Height");
CodeFieldReferenceExpression areaReference =
new CodeFieldReferenceExpression(
new CodeThisReferenceExpression(), "Area");
// Declaring a return statement for method ToString.
CodeMethodReturnStatement returnStatement =
new CodeMethodReturnStatement();
// This statement returns a string representation of the width,
// height, and area.
string formattedOutput = "The object:" + Environment.NewLine +
" width = {0}," + Environment.NewLine +
" height = {1}," + Environment.NewLine +
" area = {2}";
returnStatement.Expression =
new CodeMethodInvokeExpression(
new CodeTypeReferenceExpression("System.String"), "Format",
new CodePrimitiveExpression(formattedOutput),
widthReference, heightReference, areaReference);
toStringMethod.Statements.Add(returnStatement);
targetClass.Members.Add(toStringMethod);
}
/// <summary>
/// Add a constructor to the class.
/// </summary>
public void AddConstructor()
{
// Declare the constructor
CodeConstructor constructor = new CodeConstructor();
constructor.Attributes =
MemberAttributes.Public | MemberAttributes.Final;
// Add parameters.
constructor.Parameters.Add(new CodeParameterDeclarationExpression(
typeof(System.Double), "width"));
constructor.Parameters.Add(new CodeParameterDeclarationExpression(
typeof(System.Double), "height"));
// Add field initialization logic
CodeFieldReferenceExpression widthReference =
new CodeFieldReferenceExpression(
new CodeThisReferenceExpression(), "widthValue");
constructor.Statements.Add(new CodeAssignStatement(widthReference,
new CodeArgumentReferenceExpression("width")));
CodeFieldReferenceExpression heightReference =
new CodeFieldReferenceExpression(
new CodeThisReferenceExpression(), "heightValue");
constructor.Statements.Add(new CodeAssignStatement(heightReference,
new CodeArgumentReferenceExpression("height")));
targetClass.Members.Add(constructor);
}
/// <summary>
/// Add an entry point to the class.
/// </summary>
public void AddEntryPoint()
{
CodeEntryPointMethod start = new CodeEntryPointMethod();
CodeObjectCreateExpression objectCreate =
new CodeObjectCreateExpression(
new CodeTypeReference("CodeDOMCreatedClass"),
new CodePrimitiveExpression(5.3),
new CodePrimitiveExpression(6.9));
// Add the statement:
// "CodeDOMCreatedClass testClass =
// new CodeDOMCreatedClass(5.3, 6.9);"
start.Statements.Add(new CodeVariableDeclarationStatement(
new CodeTypeReference("CodeDOMCreatedClass"), "testClass",
objectCreate));
// Creat the expression:
// "testClass.ToString()"
CodeMethodInvokeExpression toStringInvoke =
new CodeMethodInvokeExpression(
new CodeVariableReferenceExpression("testClass"), "ToString");
// Add a System.Console.WriteLine statement with the previous
// expression as a parameter.
start.Statements.Add(new CodeMethodInvokeExpression(
new CodeTypeReferenceExpression("System.Console"),
"WriteLine", toStringInvoke));
targetClass.Members.Add(start);
}
/// <summary>
/// Generate CSharp source code from the compile unit.
/// </summary>
/// <param name="filename">Output file name</param>
public void GenerateCSharpCode(string fileName)
{
CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");
CodeGeneratorOptions options = new CodeGeneratorOptions();
options.BracingStyle = "C";
using (StreamWriter sourceWriter = new StreamWriter(fileName))
{
provider.GenerateCodeFromCompileUnit(
targetUnit, sourceWriter, options);
}
}
/// <summary>
/// Create the CodeDOM graph and generate the code.
/// </summary>
static void Main()
{
Sample sample = new Sample();
sample.AddFields();
sample.AddProperties();
sample.AddMethod();
sample.AddConstructor();
sample.AddEntryPoint();
sample.GenerateCSharpCode(outputFileName);
}
}
}
當編譯並執行先前的範例後,會產生下列原始程式碼。
'--------------------------------------------------------------------------
' <auto-generated>
' This code was generated by a tool.
' Runtime Version:2.0.50727.42
'
' Changes to this file may cause incorrect behavior and will be lost if
' the code is regenerated.
' </auto-generated>
'--------------------------------------------------------------------------
Option Strict Off
Option Explicit On
Imports System
Namespace CodeDOMSample
Public NotInheritable Class CodeDOMCreatedClass
'The width of the object.
Private widthValue As Double
'The height of the object.
Private heightValue As Double
Public Sub New(ByVal width As Double, ByVal height As Double)
MyBase.New
Me.widthValue = width
Me.heightValue = height
End Sub
'The width property for the object.
Public ReadOnly Property Width() As Double
Get
Return Me.widthValue
End Get
End Property
'The Height property for the object.
Public ReadOnly Property Height() As Double
Get
Return Me.heightValue
End Get
End Property
'The Area property for the object.
Public ReadOnly Property Area() As Double
Get
Return (Me.widthValue * Me.heightValue)
End Get
End Property
Public Overrides Function ToString() As String
Return String.Format("The object:"& _
Global.Microsoft.VisualBasic.ChrW(13)& _
Global.Microsoft.VisualBasic.ChrW(10)& _
" width = {0},"&Global.Microsoft.VisualBasic.ChrW(13)& _
Global.Microsoft.VisualBasic.ChrW(10)& _
" height = {1},"&Global.Microsoft.VisualBasic.ChrW(13)& _
Global.Microsoft.VisualBasic.ChrW(10)&" area = {2}", _
Me.Width, Me.Height, Me.Area)
End Function
Public Shared Sub Main()
Dim testClass As CodeDOMCreatedClass = _
New CodeDOMCreatedClass(5.3, 6.9)
System.Console.WriteLine(testClass.ToString)
End Sub
End Class
End Namespace
//--------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:2.0.50727.42
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//--------------------------------------------------------------------------
namespace CodeDOMSample
{
using System;
public sealed class CodeDOMCreatedClass
{
// The width of the object.
private double widthValue;
// The height of the object.
private double heightValue;
public CodeDOMCreatedClass(double width, double height)
{
this.widthValue = width;
this.heightValue = height;
}
// The Width property for the object.
public double Width
{
get
{
return this.widthValue;
}
}
// The Height property for the object.
public double Height
{
get
{
return this.heightValue;
}
}
// The Area property for the object.
public double Area
{
get
{
return (this.widthValue * this.heightValue);
}
}
public override string ToString()
{
return string.Format(
"The object:\r\n width = {0},\r\n height = {1},\r\n area = {2}",
this.Width, this.Height, this.Area);
}
public static void Main()
{
CodeDOMCreatedClass testClass = new CodeDOMCreatedClass(5.3, 6.9);
System.Console.WriteLine(testClass.ToString());
}
}
}
產生的原始程式碼會在編譯及執行時,產生下列輸出。
The object:
width = 5.3,
height = 6.9,
area = 36.57
編譯程式碼
- 此程式碼範例需要有 FullTrust 權限集合,才能執行成功。