Browse DevX
Sign up for e-mail newsletters from DevX


Generate .NET Code in Any Language Using CodeDOM  : Page 2

The CodeDOM namespace contains classes that abstract the idea of code. After defining code in this abstract manner, you can use a language-specific CodeProvider class to generate code in any .NET language from that single abstract CodeDOM representation.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

Generate a Simple Class (Steps 1-5)
In this section you'll build a simple class that:

  • holds a single value
  • knows how to print that value to the Output window
Create a new Windows Forms application and add the statement Imports System.CodeDOM to the top of the class module. Add a button named btnSimpleClass to the form. You'll define and generate the class code in that button's Click event handler.

To create the code, I'll step through the process steps from above, in detail:

1. Create a namespace
The CodeNamespace class represents a namespace.

' create a namespace ns = New CodeNamespace("Simple")

A CodeNamespace is a top-level object in the code object model. The CodeNamespace exposes an Imports property that returns a CodeNamespaceImportCollection collection containing the namespaces you want to import. Add each namespace using the collection's Add method

2. Import namespaces

ns.Imports.Add(New CodeNamespaceImport _ ("System")) ns.Imports.Add(New CodeNamespaceImport _ ("System.Diagnostics")) ns.Imports.Add(New CodeNamespaceImport _ ("System.Text"))

The CodeNamespace object exposes a Types property that returns a CodeTypeDeclarationCollection collection containing the classes (CodeTypeDeclaration objects) in that namespace. When you first create the CodeNamespace, its Types collection is empty. The Types collection holds classes, interfaces, structures, or enumerations, all of which are "types." You add each type to the collection using the Add method. For this example, create one class and add it to the namespace you created in step one.

3. Create a class and add it to the namespace
Use the CodeTypeDeclaration class to create a new class type. (You would also use the CodeTypeDeclaration to create a new interface, structure, or enumeration type.) One overloaded constructor accepts the name of the new type as a parameter.

' create a new class named "SimpleClass" Dim aClass As New CodeTypeDeclaration _ ("SimpleClass") ' add the class to the namespace's ' Types collection ns.Types.Add(aClass)

4. Create member fields for the class, defining the name and type for each field
Each CodeTypeDeclaration object has a Members property that is an instance of the CodeTypeMemberCollection class. As you probably expect by now, the collection accepts instances of the CodeTypeMember class. A CodeTypeMember is a base class that represents a field, a method (Sub or Function), a constructor, a property, or a nested type, collectively termed members of the class. Use the appropriate derived class to represent each member. For example, to create a new field, use the CodeMemberField class. To add a new method, use the CodeMemberMethod class, etc.

For this example, create one private Integer field. Note that "Integer" isn't a valid type; use System.Int32 instead. Because the class imports the System namespace, you can use simply "Int32" and everything works properly.

' add an Integer field named "mNumber" Dim aField As New CodeMemberField _ ("Int32", "mNumber") ' make it private aField.Attributes = MemberAttributes.Private ' add it to the class Members collection. aClass.Members.Add(aField)

5. Create methods and properties
Create the methods and properties as new CodeTypeMembers, using the appropriate derived class. Each CodeTypeMember has properties that let you specify the member's scope (Attributes property), parameters (Parameters property), return type ReturnType property, and contained code (Statements property). Members that may hold more than one value are exposed as collection types. For example, the Attributes, Parameters, and Statements properties are all collection types. You populate these by creating type instances, and using each collection's Add method to add them to the collection. The following code creates the SimpleClass constructor.

' create a public class constructor Dim aClassConstructor As New CodeConstructor() ' make it public aClassConstructor.Attributes = _ MemberAttributes.Public ' the constructor accepts one Integer ' parameter named "aNumber" aClassConstructor.Parameters.Add( _ New CodeParameterDeclarationExpression( _ New CodeTypeReference("Integer"), "aNumber")) ' assign the value of "aNumber" to the ' mNumber field. The following code ' will output "Me.mNumber = aNumber" in VB.NET ' or "this.mNumber = aNumber" in C# aClassConstructor.Statements.Add( _ New CodeAssignStatement( _ New CodeFieldReferenceExpression( _ New CodeThisReferenceExpression(), _ "Number"), _ New CodeArgumentReferenceExpression _ ("aNumber"))) ' add the constructor to the class aClass.Members.Add(aClassConstructor)

When you generate all the CodeDOM code you've seen thus far using the VBCodeGenerator class, the result is:

' generator output in VB.NET Imports System Imports System.Diagnostics Imports System.Text Namespace Simple Public Class SimpleClass Private mNumber As Int32 Public Sub New(ByVal aNumber As [Integer]) MyBase.New Me.Number = aNumber End Sub

Compare the constructor code to the output. Note that the VB code generator understands VB.NET syntax well enough to perform some tasks automatically. For example, creating a constructor generates a Sub New automatically. The End Sub is also automatic. In fact, the code generator creates all End <type> statements (or end brackets if you generate C#) automatically. The CodeThisReferenceExpression in the preceding code is the same as writing Me in VB.NET or this in C#.

Creating a constructor and creating a method are essentially the same process, although the CodeDOM classes you need differ slightly. The following code creates a public read-only property named "Number."

' create a public readonly property ' named "Number" that returns an Integer ' create a CodeMemberProperty object ' to represent the property Dim p As New CodeMemberProperty() ' give the new property a name p.Name = "Number" ' make it public p.Attributes = MemberAttributes.Public p.Type = New CodeTypeReference("Int32") p.HasGet = True p.HasSet = False

Pay attention to the HasGet and HasSet properties—you'll read more about them in the next section.

Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date