设为首页收藏本站language 语言切换
查看: 1475|回复: 0
收起左侧

CodeDom:语言的界限在这里消失

[复制链接]
发表于 2010-2-25 10:30:01 | 显示全部楼层 |阅读模式
<p >  .NET推崇这样一种思想:相对于框架而言,语言处于从属、次要的地位。CodeDom名称空间中包含的类是这一思想的集中体现。我们可以用CodeDom构造一个树或图,用System.CodeDom名称空间的类填充它,完成后,用对应各种.NET语言的CodeProvider对象将树结构转换成该种语言的代码。要更换一种语言,简单到只需更换一下最后用到的CodeProvider对象。 <p >  设想一下,利用这一技术,我们至少能够: <p >  ·查询存储过程的元数据,构造出一个负责参数绑定的类。 <p >  ·查询程序集的manifest,构造出一个对每个函数执行单元测试的类。 <p >  ·为开发组用到的每一种语言生成样板代码。 <p >  ·只需写一份范例代码,就可以让用户自由选择他们要查看哪一种语言的版本。 <p >  ·自定义模板语法,经解析后生成任意语言的代码。 <p >  ·如果要学习某种不熟悉的语言,可以生成该语言的代码,然后将它与熟悉的语言比较。 <p >  <b>一、基本操作</b><p >  System.CodeDom名称空间包含了许多以语言中立的形式描述常见程序结构的对象,每一种语言的细节则由与该种语言对应的CodeProvider对象负责处理。例如,CodeConditionStatement包含一个TrueStatements集合、一个FalseStatements集合和一个条件属性(Condition attribute),但不涉及条件语句块要用“end if”还是右花括号“}”结束,这部分细节由CodeProvider处理。有了这一层抽象,我们就可以描述待生成的代码结构,然后将它以任意语言的形式输出,却不必斤斤计较于各种与特定语言有关的细节问题。同时,这种抽象也为我们通过程序改变代码的结构带来了方便。例如,当我们发现某个方法需要增加一个参数时,就可以将参数加入到该方法的Parameters集合,根本无须改动已生成的代码逻辑。 <p >  我们在本文中要用到的大部分对象来自System.CodeDom名称空间,其余对象主要来自各个与特定语言有关的名称空间,例如Microsoft.CSharp名称空间、Microsoft.VisualBasic名称空间、Microsoft.JScript名称空间和Microsoft.VJSharp名称空间。所有这些面向特定语言的名称空间都包含各自的CodeProvider对象。最后,System.CodeDom.Complier名称空间定义ICodeGenerator接口,后者用来把生成的代码输出到一个TextWriter对象。 <p >  如果我们只要生成一些用于插件或宏的代码片断,可以利用CodeGenerator从Statement、Expression、Type等生成代码。反之,如果我们要生成的是一个完整的文件,则必须从CodeNameSpace对象入手。在本文的例子中,我们将从一个名称空间开始,示范如何加入import语句、声明类、声明方法、声明变量、实现一个循环结构、索引一个数组,最后,我们将这些技术结合起来,得到一个大家都熟悉的程序。 <p >  <b>1.1 初始化名称空间</b><p >  初始化名称空间的代码类似下面这种形式: <p ><ccid_nobr><table width="550" border="1" cellspacing="0" cellpadding="2" bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"><tr><td bgcolor="e6e6e6" class="code"><pre><ccid_code>private CodeNameSpace InitializeNameSpace(string Name) {  // 初始化CodeNameSpace变量,指定名称空间的名称  CodeNameSpace CurrentNameSpace = new CodeNamespace (Name);  // 将一些名称空间加入到要导入的名称空间集合。  // 各种语言如何导入名称空间的细节由每种语言对应  // 的CodeProvider分别处理。  CurrentNameSpace.Imports.Add (new CodeNamespaceImport(&quot;System&quot;));  CurrentNameSpace.Imports.Add (new CodeNamespaceImport(&quot;System.Text&quot;));  return CurrentNameSpace;}</ccid_code></pre></td></tr></table></ccid_nobr><p >  这段代码定义了一个新的名称空间,并导入System和System.Text名称空间。 <p >  <b>1.2 创建类</b><p >  声明一个新类的代码类似下面这种形式: <p ><ccid_nobr><table width="550" border="1" cellspacing="0" cellpadding="2" bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"><tr><td bgcolor="e6e6e6" class="code"><pre><ccid_code>private CodeTypeDeclaration CreateClass (string Name){  // 新建一个CodeTypeDeclaration对象,指定要创建的类的名称  CodeTypeDeclaration ctd = new CodeTypeDeclaration (Name);  // 指定这个CodeType是一个类,而不是一个枚举变量或struct  ctd.IsClass = true;  // 这个类的访问类型是public  ctd.Attributes = MemberAttributes.Public;  // 返回新创建的类  return ctd; }</ccid_code></pre></td></tr></table></ccid_nobr><p >  CreateClass函数新建一个指定名称的类,做好为该类植入方法、属性、事件的准备。 <p >  <b>1.3 创建方法</b><p >  声明一个新函数的代码类似下面这种形式: <p ><ccid_nobr><table width="550" border="1" cellspacing="0" cellpadding="2" bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"><tr><td bgcolor="e6e6e6" class="code"><pre><ccid_code>private CodeEntryPointMethod CreateMethod(){  // 创建一个方法  CodeEntryPointMethod method = new CodeEntryPointMethod();  // 指定该方法的修饰符:public,static  method.Attributes = MemberAttributes.Public |      MemberAttributes.Static;  // 返回新创建的方法  return method;}</ccid_code></pre></td></tr></table></ccid_nobr><p >  本例创建了一个CodeEntryPointMethod对象。CodeEntryPointMethod对象类似于CodeMemberMethod对象,两者的不同之处在于,CodeProvider会将CodeEntryPointMethod代表的方法作为类的入口点调用,例如作为Sub Main或void main等。对于CodeEntryPointMethod对象,方法的名称默认为Main;对于CodeMemberMethod,方法的名称必须显式指定。 <p >  <b>1.4 声明变量</b><p >  声明一个变量的代码类似下面这种形式: <p ><ccid_nobr><table width="550" border="1" cellspacing="0" cellpadding="2" bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"><tr><td bgcolor="e6e6e6" class="code"><pre><ccid_code>private CodeVariableDeclarationStatement             DeclareVariables(System.Type DataType,            string Name){  // 为将要创建的变量类型创建一个CodeTypeReference对象,  // 这使得我们不必去关注该类数据在特定语言环境中的  // 与数据类型有关的细节问题。  CodeTypeReference tr = new CodeTypeReference (DataType );  // CodeVariableDeclarationStatement对象使得我们不必纠缠于  // 与特定语言有关的下列细节:在该语言的变量声明语句中,  // 应该是数据类型在前,还是变量名称在前;声明变量时是  // 否要用到Dim之类的关键词.  CodeVariableDeclarationStatement Declaration =       new CodeVariableDeclarationStatement(tr, Name);  // CodeObjectCreateExpression负责处理所有调用构造器的细节。  // 大多数情况下应该是new,但有时要使用New。但不管怎样,  // 我们不必去关注这些由语言类型决定的细节.  CodeObjectCreateExpression  newStatement = new  CodeObjectCreateExpression ();  // 指定我们要调用其构造器的对象.  newStatement.CreateType = tr;  // 变量将通过调用其构造器的方式初始化.  Declaration.InitExpression = newStatement;  return Declaration;}</ccid_code></pre></td></tr></table></ccid_nobr><p >  每一种.NET语言都有其特定的数据类型名称,所有这些数据类型都被映射到公共的.NET语言类型。例如,对于C#中称为int的数据类型,在VB.NET中是Integer,公共的.NET类型是System.Int32。CodeTypeReference对象直接使用.NET公共数据类型,以后由每种语言的CodeProvider将它转换成符合各自语言规范的类型名称。 <p >  <b>1.5 初始化数组</b><p >  初始化一个数组的代码类似下面这种形式: <p ><ccid_nobr><table width="550" border="1" cellspacing="0" cellpadding="2" bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"><tr><td bgcolor="e6e6e6" class="code"><pre><ccid_code>private void InitializeArray (string Name,           params char[] Characters ){  // 从参数中传入的字符数组获得一个CodeTypeReference 对象,  // 以便在生成的代码中复制该数据类型.  CodeTypeReference tr = new CodeTypeReference (Characters.GetType());  // 声明一个匹配原始数组的数组  CodeVariableDeclarationStatement Declaration =    new CodeVariableDeclarationStatement (tr, Name);  // CodePrimitiveExpression代表“基本”或值数据类型,  // 例如char、int、double等等。  // 我们将用这类基本数据类型构成的一个数组来  // 初始化我们正在声明的数组。  CodePrimitiveExpression[] cpe = new     CodePrimitiveExpression[Characters.Length];  // 循环遍历原始字符数组,  // 为CodePrimitiveExpression类型的数组创建对象。  for (int i = 0; i &lt; Name.Length ; i++)  {    // 每一个CodePrimitiveExpression将有一个字符的语言    // 中立的表示。    cpe = new CodePrimitiveExpression (Characters);  }  // CodeArrayCreateExpression负责调用数组中数据类型的  // 默认构造器。  // 由于我们还传入了一个CodePrimitiveExpression的数组,  // 所以不必指定数组的大小,且数组中的每一个元素都将有  // 合适的初值。  CodeArrayCreateExpression array = new     CodeArrayCreateExpression(tr, cpe);  // 指定:该CodeArrayCreateExpression将初始化数组变量声明。  Declaration.InitExpression = array;  return Declaration;}</ccid_code></pre></td></tr></table></ccid_nobr><p >  <b>1.6 定义循环结构</b><p >  声明一个循环结构的代码类似下面这种形式: <p ><ccid_nobr><table width="550" border="1" cellspacing="0" cellpadding="2" bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"><tr><td bgcolor="e6e6e6" class="code"><pre><ccid_code>private CodeIterationStatement CreateLoop(string LoopControlVariableName){  // 声明一个新的变量,该变量将作为  // 循环控制变量  CodeVariableDeclarationStatement Declaration;  // 声明一个管理所有循环逻辑的CodeIterationStatement  CodeIterationStatement forloop = new CodeIterationStatement();  // 为动态声明的变量指定数据类型的另一种方法:  // 用typeof函数获得该数据类型的Type对象,不必  // 用到该类数据的变量  Declaration = new CodeVariableDeclarationStatement(typeof  (int),    LoopControlVariableName);  // 指定一个简单的初始化表达式:  // 将新变量设置为0  Declaration.InitExpression = new CodeSnippetExpression (&quot;0&quot;);  // 这个新声明的变量将用来初始化循环  forloop.InitStatement = Declaration;  // CodeAssignStatement用来处理赋值语句。  // 这里使用的构造器要求提供两个表达式,第一个位于  // 赋值语句的左边,第二个位于赋值语句的右边。  // 另一种办法是:调用默认的构造器,然后分别显式设置  // 左、右两个表达式。  CodeAssignStatement assignment = new CodeAssignStatement(     new CodeVariableReferenceExpression(LoopControlVariableName),     new CodeSnippetExpression (LoopControlVariableName + &quot; + 1&quot; ));  // 在循环迭代中使用赋值语句。  forloop.IncrementStatement = assignment;  // 当循环控制变量超出数组中的字符个数时,  // 循环结束  forloop.TestExpression = new CodeSnippetExpression    (LoopControlVariableName + &quot; &lt; Characters.Length&quot;);  return forloop;}</ccid_code></pre></td></tr></table></ccid_nobr><p >  注意,这里我们用typeof函数直接获得循环控制变量的数据类型的Type对象,而不是通过声明一个CodeTypeReference对象的方式。这是CodeVariableDeclartionStatement的又一个构造器,实际上其构造器的总数多达7种。 <p >  <b>1.7 索引数组</b><p >  索引一个数组的代码类似下面这种形式: <p ><ccid_nobr><table width="550" border="1" cellspacing="0" cellpadding="2" bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"><tr><td bgcolor="e6e6e6" class="code"><pre><ccid_code>private CodeArrayIndexerExpression   CreateArrayIndex(string ArrayName, string IndexValue  ){  // 新建一个CodeArrayIndexerExpression  CodeArrayIndexerExpression index = new CodeArrayIndexerExpression ();  // Indices属性是一个能够支持多维数组的集合。不过这里我们只需要  // 一个简单的一维数组。  index.Indices.Add ( new CodeVariableReferenceExpression (IndexValue));  // TargetObject指定了要索引的数组的名称。  index.TargetObject = new CodeSnippetExpression (ArrayName);  return index;}</ccid_code></pre></td></tr></table></ccid_nobr><p >  CodeArrayIndexerExpression对象处理数组索引方式的种种差异。例如,在C#中数组以ArrayName[IndexValue]的方式索引;但在VB.NET中,数组以ArrayName(IndexValue)的方式索引。CodeArrayIndexerExpression允许我们忽略这种差异,将注意力集中到其他更重要的问题,例如要索引哪一个数组、要访问第几个数组元素。 <p >  <b>二、装配出树结构</b><p >  我们可以把前面定义的所有函数加入到一个类,通过构造器初始化,例如: <p ><ccid_nobr><table width="550" border="1" cellspacing="0" cellpadding="2" bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"><tr><td bgcolor="e6e6e6" class="code"><pre><ccid_code>public CodeDomProvider(){           CurrentNameSpace = InitializeNameSpace(&quot;TestSpace&quot;);  CodeTypeDeclaration ctd = CreateClass (&quot;HelloWorld&quot;);  // 把类加入到名称空间  CurrentNameSpace.Types.Add (ctd);  CodeEntryPointMethod mtd = CreateMethod();  // 把方法加入到类  ctd.Members.Add (mtd);  CodeVariableDeclarationStatement VariableDeclaration =     DeclareVariables (typeof (StringBuilder), &quot;sbMessage&quot;);  // 把变量声明加入到方法  mtd.Statements.Add (VariableDeclaration);  CodeVariableDeclarationStatement array = InitializeArray    (&quot;Characters&quot;, 'H', 'E', 'L', 'L', 'O', ' ',     'W', 'O', 'R', 'L', 'D');  // 把数组加入到方法  mtd.Statements.Add (array);  CodeIterationStatement loop = CreateLoop(&quot;intCharacterIndex&quot;);  // 把循环加入到方法  mtd.Statements.Add (loop);  // 数组索引  CodeArrayIndexerExpression index = CreateArrayIndex(&quot;Characters&quot;,    &quot;intCharacterIndex&quot;);  // 加入一个语句,它将调用sbMessage对象的“Append”方法  loop.Statements.Add (new CodeMethodInvokeExpression (    new CodeSnippetExpression (&quot;sbMessage&quot;),&quot;Append&quot;,     index));  // 循环结束后,输出所有字符追加到sbMessage对象  // 后得到的结果  mtd.Statements.Add (new CodeSnippetExpression    (&quot;Console.WriteLine (sbMessage.ToString())&quot;));}</ccid_code></pre></td></tr></table></ccid_nobr><p >  构造器的运行结果是一个完整的CodeDom树结构。可以看到,至此为止我们的所有操作都独立于目标语言。最后生成的代码将以属性的形式导出。 <p >  <b>三、输出生成结果</b><p >  构造好CodeDom树之后,我们就可以较为方便地将代码以任意.NET语言的形式输出。每一种.NET语言都有相应的CodeProvider对象,CodeProvider对象的CreateGenerator方法能够返回一个实现了ICodeGenerator接口的对象。ICodeGenerator接口定义了用来生成代码的所有方法,而且允许我们定义一个用来简化属性输出的辅助方法。下面的辅助方法GenerateCode负责设置好合适的TextWriter以供输出代码,以字符串的形式返回结果文本。 <p ><ccid_nobr><table width="550" border="1" cellspacing="0" cellpadding="2" bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"><tr><td bgcolor="e6e6e6" class="code"><pre><ccid_code>private string GenerateCode (ICodeGenerator CodeGenerator){  // CodeGeneratorOptions允许我们指定各种供代码生成器  // 使用的格式化选项  CodeGeneratorOptions cop = new CodeGeneratorOptions();  // 指定格式:花括号的位置  cop.BracingStyle = &quot;C&quot;;  // 指定格式:代码块的缩进方式  cop.IndentString = &quot;  &quot;;  // GenerateCodeFromNamespace要求传入一个TextWriter以  // 容纳即将生成的代码。这个TextWriter可以是一个StreamWriter、  // 一个StringWriter或一个IndentedTextWriter。  // StreamWriter可用来将代码输出到文件。  // StringWriter可绑定到StringBuilder,后者可作为一个变量引用。  // 在这里,我们把一个StringWriter绑定到StringBuilder sbCode。  StringBuilder sbCode  = new StringBuilder();  StringWriter sw  = new StringWriter(sbCode);  // 生成代码!  CodeGenerator.GenerateCodeFromNamespace(CurrentNameSpace, sw,cop);  return sbCode.ToString();}</ccid_code></pre></td></tr></table></ccid_nobr><p >  有了这个辅助函数,要获取各种语言的代码就相当简单了: <p ><ccid_nobr><table width="550" border="1" cellspacing="0" cellpadding="2" bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"><tr><td bgcolor="e6e6e6" class="code"><pre><ccid_code>public string VBCode {  get   {    VBCodeProvider provider =  new VBCodeProvider ();    ICodeGenerator codeGen = provider.CreateGenerator ();    return GenerateCode (codeGen);  }}public string JScriptCode{  get   {    JScriptCodeProvider provider = new JScriptCodeProvider ();    ICodeGenerator codeGen = provider.CreateGenerator ();    return GenerateCode(codeGen);  }}public string JSharpCode {  get   {    VJSharpCodeProvider provider = new VJSharpCodeProvider ();    ICodeGenerator codeGen = provider.CreateGenerator ();    return GenerateCode (codeGen);  }}public string CSharpCode {  get   {    CSharpCodeProvider provider = new CSharpCodeProvider();    ICodeGenerator codeGen = provider.CreateGenerator ();    return GeneratorCode (codeGen);  }}</ccid_code></pre></td></tr></table></ccid_nobr><p >  <b>四、显示出生成的代码</b><p >  为输出代码,我们要用到一个简单的.aspx文件,它有四个标签,分别对应一种.NET语言: <p ><ccid_nobr><table width="550" border="1" cellspacing="0" cellpadding="2" bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"><tr><td bgcolor="e6e6e6" class="code"><pre><ccid_code>&lt;table width=&quot;800&quot; border=&quot;1&quot;&gt;  &lt;tr&gt;    &lt;th&gt;VB.NET代码&lt;/th&gt;  &lt;/tr&gt;  &lt;tr &gt;    &lt;td&gt;      &lt;aspabel ID=&quot;vbCode&quot; Runat=&quot;server&quot; CssClass=&quot;code&quot;&gt;      &lt;/aspabel&gt;    &lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;    &lt;th&gt;      C#代码&lt;/th&gt;&lt;/tr&gt;  &lt;tr&gt;    &lt;td&gt;&lt;aspabel ID=&quot;csharpcode&quot; Runat=&quot;server&quot; CssClass=&quot;code&quot;&gt;    &lt;/aspabel&gt;&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;    &lt;th&gt;J#代码&lt;/th&gt;&lt;/tr&gt;  &lt;tr &gt;    &lt;td&gt;      &lt;aspabel ID=&quot;JSharpCode&quot; Runat=&quot;server&quot; CssClass=&quot;code&quot;&gt;      &lt;/aspabel&gt;    &lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;    &lt;th&gt;JScript.NET代码&lt;/th&gt;  &lt;/tr&gt;  &lt;tr&gt;    &lt;td&gt;&lt;aspabel ID=&quot;JScriptCode&quot; Runat=&quot;server&quot; CssClass=&quot;code&quot;&gt;    &lt;/aspabel&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;/table&gt;</ccid_code></pre></td></tr></table></ccid_nobr><p >  在后台执行的代码中,我们实例化一个前面创建的CodeDomProvider类的实例,把它生成的代码赋值给.aspx页面的相应标签的Text属性。为了使Web页面中显示的代码整齐美观,有必要做一些简单的格式化,替换换行符号、空格等,如下所示: <p ><ccid_nobr><table width="550" border="1" cellspacing="0" cellpadding="2" bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"><tr><td bgcolor="e6e6e6" class="code"><pre><ccid_code>private string FormatCode (string CodeToFormat){  string FormattedCode = Regex.Replace (CodeToFormat, &quot;\n&quot;, &quot;&lt;br&gt;&quot;);  FormattedCode = Regex.Replace (FormattedCode,  &quot;  &quot; , &quot;&amp;nbsp;&quot;);  FormattedCode = Regex.Replace (FormattedCode, &quot;,&quot;, &quot;, &quot;);  return FormattedCode;}</ccid_code></pre></td></tr></table></ccid_nobr><p >  下面把生成的代码显示到Web页面: <p ><ccid_nobr><table width="550" border="1" cellspacing="0" cellpadding="2" bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"><tr><td bgcolor="e6e6e6" class="code"><pre><ccid_code>private void Page_Load(object sender, System.EventArgs e){  HelloWorld.CodeDomProvider  codegen = new HelloWorld.CodeDomProvider ();  vbCode.Text = FormatCode (codegen.VBCode);  csharpcode.Text = FormatCode (codegen.CSharpCode);  JScriptCode.Text = FormatCode (codegen.JScriptCode);  JSharpCode.Text = FormatCode (codegen.JSharpCode);  Page.EnableViewState = false;}</ccid_code></pre></td></tr></table></ccid_nobr><p >  输出结果如下: <p ><ccid_nobr><table width="550" border="1" cellspacing="0" cellpadding="2" bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"><tr><td bgcolor="e6e6e6" class="code"><pre><ccid_code>VB.NET代码Imports System Imports System.Text Namespace HelloWorld      Public Class Hello_World          Public Shared Sub Main()       Dim sbMessage As System.Text.StringBuilder = _                         New System.Text.StringBuilder       Dim Characters() As Char = New Char() {_           Microsoft.VisualBasic.ChrW(72),  _           Microsoft.VisualBasic.ChrW(69),  _           Microsoft.VisualBasic.ChrW(76),  _           Microsoft.VisualBasic.ChrW(76),  _           Microsoft.VisualBasic.ChrW(79),  _           Microsoft.VisualBasic.ChrW(32),  _           Microsoft.VisualBasic.ChrW(87),  _           Microsoft.VisualBasic.ChrW(79),  _           Microsoft.VisualBasic.ChrW(82),  _           Microsoft.VisualBasic.ChrW(76),  _           Microsoft.VisualBasic.ChrW(68)}       Dim intCharacterIndex As Integer = 0       Do While intCharacterIndex &lt; Characters.Length         sbMessage.Append(Characters(intCharacterIndex))         intCharacterIndex = intCharacterIndex + 1       Loop       Console.WriteLine (sbMessage.ToString())     End Sub   End Class End Namespace C#代码namespace  HelloWorld {     using  System;     using  System.Text;         public  class  Hello_World     {         public  static  void  Main()         {             System.Text.StringBuilder  sbMessage  =  new                   System.Text.StringBuilder();             char[]  Characters  =  new  char[]  {                     'H',                     'E',                     'L',                     'L',                     'O',                     '  ',                     'W',                     'O',                     'R',                     'L',                     'D'};             for  (int  intCharacterIndex  =  0;                     intCharacterIndex  &lt;  Characters.Length;                  intCharacterIndex  =  intCharacterIndex  +  1)             {                 sbMessage.Append(Characters[intCharacterIndex]);             }             Console.WriteLine  (sbMessage.ToString());         }     } } J#代码package  HelloWorld; import  System.*; import  System.Text.*; public  class  Hello_World {     public  static  void  main(String[]  args)     {         System.Text.StringBuilder  sbMessage  =  new                System.Text.StringBuilder();         char[]  Characters  =  new  char[]         {                 'H',                 'E',                 'L',                 'L',                 'O',                 '  ',                 'W',                 'O',                 'R',                 'L',                 'D'}         ;         for  (int  intCharacterIndex  =  0;                 intCharacterIndex  &lt;  Characters.Length;              intCharacterIndex  =  intCharacterIndex  +  1)         {             sbMessage.Append(Characters[intCharacterIndex]);         }         Console.WriteLine  (sbMessage.ToString());     } } JScript.NET代码//@cc_on //@set @debug(off) import System; import System.Text; package HelloWorld {      public class Hello_World   {          public static function Main()     {       var sbMessage : System.Text.StringBuilder =             new System.Text.StringBuilder();       var Characters : char[] =             ['H', 'E', 'L', 'L', 'O', ' ', 'W', 'O', 'R', 'L', 'D'];       for (var intCharacterIndex : int = 0;       ; intCharacterIndex &lt; Characters.Length;       intCharacterIndex = intCharacterIndex + 1)       {         sbMessage.Append(Characters[intCharacterIndex]);       }       Console.WriteLine (sbMessage.ToString());     }   } } HelloWorld.Hello_World.Main();</ccid_code></pre></td></tr></table></ccid_nobr><p >  总结:CodeDom体现了.NET中语言的重要性不如框架的思想。本文示范了如何运用一些常用的CodeDom类,几乎每一个使用CodeDom技术的应用都要用到这些类。作为一种结构化的代码生成技术,CodeDom有着无限的潜能,唯一的约束恐怕在于人们的想象力。 <p ><center class="name02">(责任编辑:西门吹雪)</center><p align="center"></p></p>
您需要登录后才可以回帖 登录 | 论坛注册

本版积分规则

QQ|Archiver|手机版|小黑屋|sitemap|鸿鹄论坛 ( 京ICP备14027439号 )  

GMT+8, 2025-4-6 12:17 , Processed in 0.076637 second(s), 23 queries , Redis On.  

  Powered by Discuz!

  © 2001-2025 HH010.COM

快速回复 返回顶部 返回列表