您的位置:首页 > 其它

CodeDOM浅析(上)

2004-11-29 11:40 323 查看


CodeDOM用得差不多了,不能天天只管写代码写呀写的,闲下来之余总是要想一想它是如何来实现这样的功能的呢?就那样建立起来一个CodeDOM的类,然后就可以去生成我们希望的代码,且可以动态的去编译它。

MS的东西没有源代码,不过现在可以用Reflector这样的好工具来粗粗地探究一下里面到底是如何干的(当然如果IL过关的话,也可以直接用Ildasm来看)。这一点还真是不赖。

提到CodeDOM实际上是讲.NET Farmework下的System.CodeDom与System.CodeDom.Compiler这两个命名空间。

CodeDOM的中文全名就是“代码文档对象模型”。要知道模型这个东西其实是很虚的,它基本是不干实事。它那里面那么多的类,从最基本的Expression与Statement开始,一点点的堆起来,最后得到一个表示Namespace或CompileUnit类,归根结底在System.CodeDom这个命名空间里你new来new去只能是得到一些Object而已,而Object是什么呢,就是内存里的一点点数据,我们根本看不见摸不着(否则也用不着去O/R Mapping了),只有通过System.CodeDom.Compiler这个命名空间里的东西才能把它表现出来。前一个命名空间在于构造,后一个命名空间在于表现。构造就是搭个架子,把里面的各个部分聚合聚合,连接连接,这个一点点奥秘都没有,所有也不去深究了。

(说起DOM,想起了XML里的那个DOM,那个东西也跟这相差不多,不过XML里面的东西比Code要复杂多了。)

打开System.CodeDom.Compiler这个命名空间,里面的成员比起System.CodeDom来是少得多了,不过虽然少,但来得实在,这里的东西是很实的,个个都很管用。

前面讲《动态生成与编译》的时候提到过了,这里主要有三大接口:ICodeCompiler、ICodeGenerator、ICodeParser以及创建这些接口实现类用的CodeDomProvider。能够用同一份CodeDOM来生成不同程序语言的代码及编译生成的代码,实现这样的一种功能的关键所在其实就是在Provider这里。CodeDomProvider是个抽象类,在.NET下 任何某一种程序语言如果要实现动态生成与编译的功能,就要提供一个相应的Provider。如C#是CSharpCodeProvider,VB.NET是VBCodeProvider等(Delphi2005也提供了CodeDOM的功能,所以它也有相应的Provider的)。

下面的只以C#为例。CSharpCodeProvider这个类在Microsoft.CSharp这个命名空间

先来生成的,看看ICodeGenerator接口的GenerateCodeFromCompileUnit()方法实现(接口中的其他方法从这里都会调用到)。

抽象类public abstract class CodeGenerator :ICodeGenerator 里提供了接口的实现:
[code]

下面再剥一层,把Type露出来了。

protected virtual void GenerateNamespace(CodeNamespace e)protected override void GenerateAssignStatement(CodeAssignStatement e) base.GenerateExpression(e.Left);
base.Output.Write(" = ");
base.GenerateExpression(e.Right);
if (!this.forLoopHack) base.Output.WriteLine(";");
}
}

生成左边的,写入一个“=”号,然后生成右边的,最后写一个“;”(如果在for循环头部里的赋值语句就特殊点,不要这个“;”了)。Output是什么?就是根据接口方法GenerateCodeFromCompileUnit()刚开始传进来的那个TextWriter参数设置的属性。再看几个Generate方法,能看到很多的base.Output.Write()这样的语句。

很明白了,Generate过程就是从上往下层层分解得到Expression与Statement,一字符串一字符串的往TextWriter里写的。

所以如果你要的动态程序不需要很灵活(用少数几个变量,再加点条件判断就能搞定的那种),而且又用不着多语言的话,大可不必用CodeDOM,还是自己搞个TextWriter来写省事又省心
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: