• C#动态生成代码和程序集


    以下代码动态生成cs文件

    编译为Assembly 

    之后可以使用AppDomain.Load 加载程序集,并新建类型

    public static void Test()
    {
    //声明代码的部分
    CodeCompileUnit compunit = new CodeCompileUnit();
    CodeNamespace sample
    = new CodeNamespace("命名空间");
    compunit.Namespaces.Add(sample);

    //引用命名空间
    sample.Imports.Add(new CodeNamespaceImport("System"));//导入System命名空间
    sample.Imports.Add(new CodeNamespaceImport("System.Linq"));//导入System.Linq命名空间

    //在命名空间下添加一个类
    CodeTypeDeclaration wrapProxyClass = new CodeTypeDeclaration("类名");
    //wrapProxyClass.BaseTypes.Add(baseType);// 如果需要的话 在这里声明继承关系 (基类 , 接口)
    wrapProxyClass.CustomAttributes.Add(new CodeAttributeDeclaration("Serializable"));//添加一个Attribute到class上
    sample.Types.Add(wrapProxyClass);//把这个类添加到命名空间 ,待会儿才会编译这个类

    //为这个类添加一个无参构造函数 其实不添加也没事的, 只是做个demo而已
    CodeConstructor constructor = new CodeConstructor();
    constructor.Attributes
    = MemberAttributes.Public;
    wrapProxyClass.Members.Add(constructor);


    //为这个类添加一个方法 public override int 方法名(string str);
    System.CodeDom.CodeMemberMethod method = new CodeMemberMethod();
    method.Name
    = "方法名";
    method.Attributes
    = MemberAttributes.Override | MemberAttributes.Public;//声明方法是公开 并且override的
    method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(string ), "str")); //这个方法添加一个输入参数
    method.ReturnType =new CodeTypeReference( typeof(int));//声明返回值的类型
    method.Statements.Add(new CodeSnippetStatement(" return 1; ")); //方法体里面很简单 直接返回 一个1;



    CSharpCodeProvider cprovider
    = new CSharpCodeProvider();

    ICodeGenerator gen
    = cprovider.CreateGenerator();
    StringBuilder fileContent
    = new StringBuilder();
    using (StringWriter sw = new StringWriter(fileContent))
    {
    gen.GenerateCodeFromCompileUnit(compunit, sw,
    new CodeGeneratorOptions());//想把生成的代码保存为cs文件
    }

    ICodeCompiler compiler
    = cprovider.CreateCompiler();

    //编译参数
    CompilerParameters cp = new CompilerParameters();
    cp.ReferencedAssemblies.Add(
    "System.dll");//刚才引用了命名空间 这里是添加引用
    cp.ReferencedAssemblies.Add("System.Core.dll");//刚才引用了命名空间 这里是添加引用

    cp.OutputAssembly
    = "输出dll的位置";
    cp.GenerateInMemory
    = false; //是否只在内存中生成
    cp.IncludeDebugInformation = true;//包含调试符号 pdb文件
    cp.GenerateExecutable = false;//生成dll,不是exe
    cp.WarningLevel = 4;
    cp.TreatWarningsAsErrors
    = false;

    string filePath = "生成cs文件的保存位置";
    File.WriteAllText(filePath, fileContent.ToString());
    CompilerResults cr
    = compiler.CompileAssemblyFromFile(cp, filePath); //保存文件再进行编译 待会儿调试就比较方便了 ,可以直接断点到刚才生成的文件里面
    // CompilerResults cr = compiler.CompileAssemblyFromDom(cp, compunit); //这样的生成 不用写文件 ,就是调试麻烦
    String outputMessage = "";
    foreach (var item in cr.Output)
    {
    outputMessage
    += item + Environment.NewLine;//调试的最终输出信息
    }
    if (cr.Errors.Count > 0)//有编译错误就抛出异常
    {
    throw new Exception("error:" + Environment.NewLine + outputMessage);
    }

    }
  • 相关阅读:
    Python 以指定列宽格式化字符串
    Windows环境下QWT安装及配置
    iOS用户体验之-modal上下文
    android-调用系统的ContentPrivder获取单张图片实现剪切做头像及源代码下载
    Codeforces Round #253 (Div. 1) A Borya and Hanabi
    剑指offer 面试题9
    Memcache应用场景介绍
    [Unity-22] Coroutine协程浅析
    ZOJ 2706 Thermal Death of the Universe (线段树)
    为什么不建议用Table布局
  • 原文地址:https://www.cnblogs.com/PurpleTide/p/1957062.html
Copyright © 2020-2023  润新知