使用CodeDom动态生成一个“生成Fibonacci数列”程序(cs文件),并编译成exe
最经学习CodeDom, 看了园子里的lichdr的文章,http://www.cnblogs.com/lichdr/archive/2004/10/25/56484.html#2591176 2004.10.25 (我落后太多了)
按照其描述写成的代码:
View Code
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.CodeDom; using System.CodeDom.Compiler; using System.IO; using System.Collections; using Microsoft.CSharp; namespace CodeDomLearn { class Program { static void Main() { MethodA(); } private static void MethodA() { CodeMemberMethod FiboncMethod = new CodeMemberMethod(); FiboncMethod.Comments.Add(new CodeCommentStatement("get arrays of Fibonacci")); FiboncMethod.Name = "Fibonc"; FiboncMethod.Attributes = MemberAttributes.Private | MemberAttributes.Static; FiboncMethod.Parameters.Add(new CodeParameterDeclarationExpression(typeof(int),"n")); CodeVariableDeclarationStatement VarF = new CodeVariableDeclarationStatement(typeof(int),"F"); CodeVariableDeclarationStatement VarF1 = new CodeVariableDeclarationStatement(typeof(int), "F1", new CodePrimitiveExpression(0)); CodeVariableDeclarationStatement VarF2 = new CodeVariableDeclarationStatement(typeof(int),"F2",new CodePrimitiveExpression(1)); CodeVariableDeclarationStatement Vari = new CodeVariableDeclarationStatement(typeof(int),"i",new CodePrimitiveExpression(1)); CodeBinaryOperatorExpression test = new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("i"),CodeBinaryOperatorType.LessThanOrEqual,new CodeArgumentReferenceExpression("n")); CodeAssignStatement increment=new CodeAssignStatement(new CodeVariableReferenceExpression("i"),new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("i"),CodeBinaryOperatorType.Add,new CodePrimitiveExpression(1))); CodeAssignStatement Fassign = new CodeAssignStatement(new CodeVariableReferenceExpression("F"),new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("F1"),CodeBinaryOperatorType.Add,new CodeVariableReferenceExpression("F2"))); CodeMethodInvokeExpression wr=new CodeMethodInvokeExpression(new CodeTypeReferenceExpression("System.Console"),"WriteLine",new CodeExpression[]{new CodePrimitiveExpression("{0},Fibonacci:{1}"),new CodeVariableReferenceExpression("i"),new CodeVariableReferenceExpression("F")}); CodeAssignStatement F1assign = new CodeAssignStatement(new CodeVariableReferenceExpression("F1"), new CodeVariableReferenceExpression("F2")); CodeAssignStatement F2assign=new CodeAssignStatement(new CodeVariableReferenceExpression("F2"),new CodeVariableReferenceExpression("F")); CodeIterationStatement forloop = new CodeIterationStatement(Vari, test, increment, new CodeStatement[] {Fassign,new CodeExpressionStatement(wr),F1assign,F2assign }); FiboncMethod.Statements.Add(VarF); FiboncMethod.Statements.Add(VarF1); FiboncMethod.Statements.Add(VarF2); FiboncMethod.Statements.Add(forloop); CodeEntryPointMethod Start = new CodeEntryPointMethod(); CodeMethodInvokeExpression tips = new CodeMethodInvokeExpression(new CodeTypeReferenceExpression("System.Console"),"WriteLine",new CodePrimitiveExpression("输入n的值:")); CodeVariableDeclarationStatement VarNstr = new CodeVariableDeclarationStatement(typeof(string), "Nstr", new CodeMethodInvokeExpression(new CodeTypeReferenceExpression("System.Console.In"),"ReadLine")); CodeVariableDeclarationStatement VarN = new CodeVariableDeclarationStatement(typeof(int),"N",new CodeMethodInvokeExpression(new CodeTypeReferenceExpression("System.Convert"),"ToInt32",new CodeVariableReferenceExpression("Nstr"))); CodeMethodInvokeExpression RFibonc = new CodeMethodInvokeExpression(new CodeMethodReferenceExpression() { MethodName = "Fibonc" },new CodeExpression[]{new CodeVariableReferenceExpression("N")}); CodeMethodInvokeExpression wl = new CodeMethodInvokeExpression(new CodeTypeReferenceExpression("System.Console"),"WriteLine",new CodePrimitiveExpression("n必须大于0")); CodeConditionStatement ifcondition = new CodeConditionStatement(new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("N"),CodeBinaryOperatorType.GreaterThanOrEqual,new CodePrimitiveExpression(1)),new CodeStatement[]{new CodeExpressionStatement(RFibonc) },new CodeStatement[]{new CodeExpressionStatement(wl)}); CodeCatchClause catch1=new CodeCatchClause("ex",new CodeTypeReference("System.Exception")); //CodeMethodInvokeExpression cm=new CodeMethodInvokeExpression(new CodeTypeReference("System.Console"),"WriteLine",new CodePrimitiveExpression("12")); catch1.Statements.Add(new CodeMethodInvokeExpression(new CodeTypeReferenceExpression("System.Console"),"WriteLine",new CodePropertyReferenceExpression(new CodeArgumentReferenceExpression("ex"),"Message"))); CodeTryCatchFinallyStatement ctry = new CodeTryCatchFinallyStatement(new CodeStatement[]{VarN,ifcondition},new CodeCatchClause[]{catch1}); CodeMethodInvokeExpression read = new CodeMethodInvokeExpression(new CodeTypeReferenceExpression("System.Console"),"Read"); Start.Statements.Add(tips); Start.Statements.Add(VarNstr); Start.Statements.Add(ctry); Start.Statements.Add(read); CodeTypeDeclaration MyClass = new CodeTypeDeclaration("DemoClass"); MyClass.Members.Add(Start); MyClass.Members.Add(FiboncMethod); CodeNamespace sample = new CodeNamespace("Sample"); sample.Imports.Add(new CodeNamespaceImport("System")); sample.Types.Add(MyClass); CodeCompileUnit compunit = new CodeCompileUnit(); compunit.Namespaces.Add(sample); StreamWriter sw = new StreamWriter("mytwo.cs",false); //CSharpCodeProvider cprovider = new CSharpCodeProvider(); new CSharpCodeProvider().GenerateCodeFromCompileUnit(compunit, sw, new CodeGeneratorOptions()); sw.Close(); CompilerParameters cp = new CompilerParameters(); cp.GenerateExecutable = true; cp.ReferencedAssemblies.Add("System.dll"); cp.OutputAssembly = "mytwo.exe"; CompilerResults cr = new CSharpCodeProvider().CompileAssemblyFromFile(cp, "mytwo.cs"); } } }