Represent .NET Types in Language-Neutral Terms
Use the System.CodeDom namespace to generically represent the key members of the .NET type system.
by Andrew Troelsen
VSLive! Orlando, September 19, 2002
Note: Andrew Troelsen presented "Advanced C#: Building Programs That Dynamically Generate Other Programs" at C# Live! Orlando, Tuesday, September 17. This tip is from that session.
If you've taken the time to examine multiple managed languages, you might have noticed that the source code documents each have a similar (but not identical) form. Each language has a specific bit of syntax that allows you to define a class, members of a class, parameters of a member, and whatnot. The .NET base class library supplies an interesting namespace named System.CodeDom, which allows you to express such syntactic tokens in language-neutral terms. Formally speaking, the collection of code DOM types that describe a given source code file is termed an "object graph."
Once you have assembled a given object graph in memory, code DOM allows you to interact with a language-specific "code provider." Simply put, a code provider is a class that provides access to the ICodeGenerator interface. Using the members of this type, you can persist your object graph into the syntax of a specific .NET language. So, if you have a code DOM object graph that represents a class named SportsCar, you can dynamically persist this type in terms of C#, COBOL .NET, VB.NET, and so forth.
As you might already be aware, many command-line tools that ship with the .NET SDK already make use of code DOM technologies. For example, consider wsdl.exe. Using the /l flag, you can instruct the tool to persist your Web service proxy in a variety of different languages. By way of a friendly primer, the remainder of this discussion will examine select members of the System.CodeDom namespace and illustrate how to generically represent the key members of the .NET type system (classes, interfaces, structures, enumerations).
Representing .NET Class Types
To begin untangling the numerous possibilities of type representation, let's walk through some concrete examples. First, assume you wish to insert a number of classes into the Intertech namespace. The MyPublicClass type is a public type that derives directly from System.Object:
// This is a public class
public class MyPublicClass : object {
}
The code behind the definition is straightforward (assume a helper function named PopulateNamespace(), which populates a CodeNamespace type):
private static void PopulateNamespace(ref
CodeNamespace n)
{
// Insert a public class.
CodeTypeDeclaration c = new
CodeTypeDeclaration ("MyPublicClass");
c.IsClass = true;
c.BaseTypes.Add (typeof (System.Object) );
c.TypeAttributes = TypeAttributes.Public;
c.Comments.Add(new CodeCommentStatement(
"This is a public class"));
n.Types.Add(c);
}
As you can see, the process begins by creating a new CodeTypeDeclaration and assigning the IsClass property to true. You specify the base class of the type through the BaseTypes property; simply pass in the type information (or string name if you can't get the literal type information) of the intended parent class. Notice that we are using the TypeAttributes.Public enumeration to specify the visibility of the MyPublicClass entity (by default, types are assumed to be visible only within the current assembly).
Back to top
|