看文字没什么好看的,看下面的代码明了(这是SDK文档上的一些例子拼拼凑凑出来的) using System; using System.CodeDom; using System.CodeDom.Compiler; using Microsoft.CSharp; using System.IO; using System.Collections; namespace DemoCodeDOM { class Class1 { [STAThread] static void Main(string[] args) { GenerateCode(); System.Console.WriteLine("Generate Code OK"); CompilerResults crt = CompileCode("GenCodeHello.cs"); //下面是编译的结果 // If errors occurred during compilation, output the compiler output and errors. if( crt.Errors.Count > 0 ) { for( int i=0; i<crt.Output.Count; i++ ) Console.WriteLine( crt.Output[i] ); for( int i=0; i<crt.Errors.Count; i++ ) Console.WriteLine( i.ToString() + ": " + crt.Errors[i].ToString() ); } else { // Display information about the compiler's exit code and the generated assembly. Console.WriteLine( "Compiler returned with result code: " + crt.NativeCompilerReturnValue.ToString() ); Console.WriteLine( "Generated assembly name: " + crt.CompiledAssembly.FullName ); if( crt.PathToAssembly == null ) Console.WriteLine( "The assembly has been generated in memory." ); else Console.WriteLine( "Path to assembly: " + crt.PathToAssembly ); // Display temporary files information. if( !crt.TempFiles.KeepFiles ) Console.WriteLine( "Temporary build files were deleted." ); else { Console.WriteLine( "Temporary build files were not deleted." ); // Display a list of the temporary build files IEnumerator enu = crt.TempFiles.GetEnumerator(); for( int i=0; enu.MoveNext(); i++ ) Console.WriteLine( "TempFile " + i.ToString() + ": " + (string)enu.Current ); } } System.Console.Read(); } //生成CodeDOM图,这一步是最复杂的部分,后面生成代码与编译都是以这里的东西为蓝本 private static CodeCompileUnit ComplieUnit() { //生成一个可编译的单元,这是最根部的东西 CodeCompileUnit compunit = new CodeCompileUnit(); CodeNamespace sample = new CodeNamespace("Sample");//定义一个名为Sample的命名空间 CodeTypeDeclaration MyClass = new CodeTypeDeclaration("DemoClass");//定义一个名为DemoClass的类 CodeEntryPointMethod Start = new CodeEntryPointMethod();//定义程序入口点,就是Main() //下面两句产生调用方法的语句 CodeMethodInvokeExpression cs = new CodeMethodInvokeExpression(new CodeTypeReferenceExpression("System.Console"), "WriteLine",new CodePrimitiveExpression("Hello World!"));//这句会产生如下的C#代码 System.Console.WriteLine("Hello World!"); CodeMethodInvokeExpression wt = new CodeMethodInvokeExpression(new CodeTypeReferenceExpression("System.Console"), "Read");//这句是 System.Console.Read(); //下面一系列语句把上述定义好的元素联接起来 compunit.Namespaces.Add(sample); sample.Imports.Add(new CodeNamespaceImport("System"));//导入System命名空间 sample.Types.Add(MyClass); MyClass.Members.Add(Start); Start.Statements.Add(cs); Start.Statements.Add(wt); return compunit; } //根据CodeDOM产生程序代码,代码文件就是GenCodeHello.cs public static void GenerateCode() { CSharpCodeProvider cprovider = new CSharpCodeProvider();//当然换个Microsoft.VisualBasic.VBCodeProvider就产生VB.NET的代码 ICodeGenerator gen = cprovider.CreateGenerator(); StreamWriter sw = new StreamWriter("GenCodeHello.cs",false); gen.GenerateCodeFromCompileUnit(ComplieUnit(),sw,new CodeGeneratorOptions()); sw.Close(); } //编译源代码 public static CompilerResults CompileCode(string filepath) { CSharpCodeProvider cprovider = new CSharpCodeProvider(); ICodeCompiler compiler = cprovider.CreateCompiler(); //编译参数 CompilerParameters cp = new CompilerParameters(new string[] {"System.dll"},filepath.Substring(0,filepath.LastIndexOf(".") + 1) + "exe",false); cp.GenerateExecutable = true;//生成EXE,不是DLL CompilerResults cr = compiler.CompileAssemblyFromFile(cp,filepath); return cr; } } } 上述的产生的程序代码实际上很简单的一个东西,就是一个控制台输出“Hello Word!”,为了不让它一闪而过,什么也看不清,再加一句read()让它等在那里而已。 上面代码的主要奥秘就是在CodeCompileUnit()这个方法里,生成CodeDOM图的基本代码其实是没什么很难的东西,主要是烦而已,就是定义一些元素,然后把它们连起来。上面为了能清晰的看出生成代码的程序结构把那些Add语句从上到下的全写在一起了。 即使要生成的代码比上面这个例子复杂多了,基本的东西还是没变的,就是定义的东西多一点而已,.NET Framework提供生成的元素是非常之多,好象大多数的语言功能都有,比如上面的定义类,还可以定义结构、枚举;类里面的方法、属性、字段及构造函数;定义Attribute;事件及委托;赋值、条件(if)、循环(for)语句;变量声明;异常处理语句;甚至还可以加注释。除了那种分支选择(switch或select)、while循环及break、continue没发现外(goto倒是看到了)其他东西应有尽有,至少还没发现什么大的功能无法实现的。真的太强大了。 今天先到这里,主要是入门。以后再好好研究,后面不知从那里开始写有点迷糊,得去找个有几代表性的程序,然后一点点分析要生成如此这般的代码应该是写成怎样的CodeDOM
public CodeCompileUnit CodeGen() { CodeCompileUnit compileUnit = new CodeCompileUnit(); CodeNamespace testNamespace = new CodeNamespace("YourNamespace"); compileUnit.Namespaces.Add(testNamespace); CodeNamespaceImport import1 = new CodeNamespaceImport("System"); testNamespace.Imports.Add(import1); CodeTypeDeclaration newType = new CodeTypeDeclaration("Data2"); newType.IsClass = true; newType.Attributes = MemberAttributes.Public; CodeMemberField field1 = new CodeMemberField("System.String", "dz"); field1.Attributes = MemberAttributes.Public; field1.Attributes = MemberAttributes.Static; CodeAssignStatement as1 = new CodeAssignStatement(new CodeVariableReferenceExpression("dz"), new CodePrimitiveExpression(@"ConfigurationManager.AppSettings[""DAL""]")); newType.Members.Add(field1); CodeMemberMethod method1 = new CodeMemberMethod(); method1.Name = "CreateObject"; method1.Attributes = MemberAttributes.Public; method1.Attributes = MemberAttributes.Static; method1.ReturnType = new CodeTypeReference("System.Object"); method1.Parameters.Add(new CodeParameterDeclarationExpression("System.String", "path")); method1.Parameters.Add(new CodeParameterDeclarationExpression("System.String", "CacheKey")); newType.Members.Add(method1); return compileUnit; }
LZ,上面的有问题,我改了下测试正确,代码在下面:public class CodeDom { public CodeCompileUnit CodeGen() { CodeCompileUnit compileUnit = new CodeCompileUnit(); CodeNamespace testNamespace = new CodeNamespace("YourNamespace");
CodeNamespaceImport import1 = new CodeNamespaceImport("System"); testNamespace.Imports.Add(import1); CodeTypeDeclaration newType = new CodeTypeDeclaration("Data2"); newType.IsClass = true; newType.Attributes = MemberAttributes.Public; CodeMemberField field1 = new CodeMemberField("System.String", "dz"); field1.Attributes = MemberAttributes.Private | MemberAttributes.Static; CodeExpression invokeExpression = new CodeIndexerExpression( new CodePropertyReferenceExpression(new CodeTypeReferenceExpression("ConfigurationManager"), "AppSettings"), new CodePrimitiveExpression("DAL")); field1.InitExpression = invokeExpression; newType.Members.Add(field1); CodeMemberMethod method1 = new CodeMemberMethod(); method1.Name = "CreateObject"; method1.Attributes = MemberAttributes.Public | MemberAttributes.Static; method1.ReturnType = new CodeTypeReference("System.Object"); method1.Parameters.Add(new CodeParameterDeclarationExpression("System.String", "path")); method1.Parameters.Add(new CodeParameterDeclarationExpression("System.String", "CacheKey")); newType.Members.Add(method1); testNamespace.Types.Add(newType); compileUnit.Namespaces.Add(testNamespace); return compileUnit; } public void OutputSourceCode(CodeCompileUnit compileUnit, CodeDomProvider provider, string strClassName) { ICodeGenerator gen = provider.CreateGenerator(); StreamWriter writer = new StreamWriter(@"e:\temp\" + strClassName + ".cs", false); CodeGeneratorOptions cop = new CodeGeneratorOptions(); cop.IndentString = " "; cop.BracingStyle = "C"; gen.GenerateCodeFromCompileUnit(compileUnit, writer, cop); writer.Close(); } }对了,别忘了500分,呵呵!
{
CodeCompileUnit compileUnit = new CodeCompileUnit();
CodeNamespace testNamespace = new CodeNamespace("YourNamespace");
compileUnit.Namespaces.Add(testNamespace);
CodeNamespaceImport import1 = new CodeNamespaceImport("System");
testNamespace.Imports.Add(import1); CodeTypeDeclaration newType = new CodeTypeDeclaration("Data2");
newType.IsClass = true;
newType.Attributes = MemberAttributes.Public; CodeMemberField field1 = new CodeMemberField("System.String", "dz");
field1.Attributes = MemberAttributes.Public;
field1.Attributes = MemberAttributes.Static;
CodeAssignStatement as1 = new CodeAssignStatement(new CodeVariableReferenceExpression("dz"), new CodePrimitiveExpression(@"ConfigurationManager.AppSettings[""DAL""]"));
newType.Members.Add(field1); CodeMemberMethod method1 = new CodeMemberMethod();
method1.Name = "CreateObject";
method1.Attributes = MemberAttributes.Public;
method1.Attributes = MemberAttributes.Static;
method1.ReturnType = new CodeTypeReference("System.Object");
method1.Parameters.Add(new CodeParameterDeclarationExpression("System.String", "path"));
method1.Parameters.Add(new CodeParameterDeclarationExpression("System.String", "CacheKey"));
newType.Members.Add(method1);
return compileUnit;
}
{
public CodeCompileUnit CodeGen()
{
CodeCompileUnit compileUnit = new CodeCompileUnit();
CodeNamespace testNamespace = new CodeNamespace("YourNamespace");
CodeNamespaceImport import1 = new CodeNamespaceImport("System");
testNamespace.Imports.Add(import1); CodeTypeDeclaration newType = new CodeTypeDeclaration("Data2");
newType.IsClass = true;
newType.Attributes = MemberAttributes.Public; CodeMemberField field1 = new CodeMemberField("System.String", "dz");
field1.Attributes = MemberAttributes.Private | MemberAttributes.Static;
CodeExpression invokeExpression = new CodeIndexerExpression(
new CodePropertyReferenceExpression(new CodeTypeReferenceExpression("ConfigurationManager"), "AppSettings"), new CodePrimitiveExpression("DAL"));
field1.InitExpression = invokeExpression;
newType.Members.Add(field1); CodeMemberMethod method1 = new CodeMemberMethod();
method1.Name = "CreateObject";
method1.Attributes = MemberAttributes.Public | MemberAttributes.Static;
method1.ReturnType = new CodeTypeReference("System.Object");
method1.Parameters.Add(new CodeParameterDeclarationExpression("System.String", "path"));
method1.Parameters.Add(new CodeParameterDeclarationExpression("System.String", "CacheKey"));
newType.Members.Add(method1);
testNamespace.Types.Add(newType);
compileUnit.Namespaces.Add(testNamespace);
return compileUnit;
} public void OutputSourceCode(CodeCompileUnit compileUnit, CodeDomProvider provider, string strClassName)
{
ICodeGenerator gen = provider.CreateGenerator();
StreamWriter writer = new StreamWriter(@"e:\temp\" + strClassName + ".cs", false);
CodeGeneratorOptions cop = new CodeGeneratorOptions();
cop.IndentString = " ";
cop.BracingStyle = "C";
gen.GenerateCodeFromCompileUnit(compileUnit, writer, cop);
writer.Close();
}
}对了,别忘了500分,呵呵!