[转]C#使用CodeDom动态生成代码

原文链接:让代码帮我们写代码(一)
示例全部来自转载的文章,这里只是简单做了一些修改,留给自己以后使用。
定义一个 ClassDescription 类来帮助描述需要生成的 class 长啥样:

public class ClassDescription
{
    public string SpaceName { get; set; }
    public string AssemblyName { get; set; }
    public string ClassName { get; set; }
    public List<PropertyDescription> Properties { get; set; }
}
public class PropertyDescription
{
    public string Name { get; set; }
    public Type Type { get; set; }
    private string des = string.Empty;
    public string Des 
    {
        get 
        {
            return (des == string.Empty) ? Name : des;
        }
        set 
        {
            if (!string.IsNullOrWhiteSpace(value)) des = value;
        }
    }
}

用 ClassDescription 来定义 User 类,它里面有 2 个属性 Name,Age:

var userClassDesc = new ClassDescription()
{
    AssemblyName = "TestAssembly",
    SpaceName = "TestSpace",
    ClassName = "User",
    Properties = new List<PropertyDescription> {
        new PropertyDescription {
            Type = typeof(string),
            Name = "Name"
        },
        new PropertyDescription
        {
            Type = typeof(int),
            Name = "Age"
        }
    }
};

使用 CodeDom 来动态生成代码:

public static Type Generate(ClassDescription clazz)
{
    const string clzTemp =
        @"
        using System;
        using System.IO;
        using System.ComponentModel;
        namespace @moduleName 
        {
        
            public class @className 
            {
                @properties
                public void Load()
                {
                    //@loadMethod
                }
                
            }
        }
        ";
    const string propTemp = 
        @"
                [Description(""propDes"")] 
                public @type @propName { get;set; }
        ";
    
    var properties = new StringBuilder("");
    foreach (var item in clazz.Properties)
    {
        string strProp = propTemp
            .Replace("@propDes", item.Des)
            .Replace("@type", item.Type.Name)                    
            .Replace("@propName", item.Name);
       
        properties.AppendLine(strProp);
    }
    string sourceCode = clzTemp
        .Replace("@moduleName", clazz.SpaceName)
        .Replace("@className", clazz.ClassName)
        .Replace("@properties", properties.ToString());
    Console.WriteLine(sourceCode);
    var codeProvider = new CSharpCodeProvider();
    CompilerParameters param = new CompilerParameters();
    param.OutputAssembly = clazz.AssemblyName;
    param.ReferencedAssemblies.Add("System.dll");
    param.ReferencedAssemblies.Add("mscorlib.dll");            
    CompilerResults result = codeProvider.CompileAssemblyFromSource(param, sourceCode);
    Type type = null;
    if (result.Errors.Count > 0)
    {
        for (int i = 0; i < result.Errors.Count; i++) 
        {
            Console.WriteLine($"Errors{i}: {result.Errors[i]}");
        }
    }
    else 
    {
        type = result.CompiledAssembly.GetType($"{clazz.SpaceName}.{clazz.ClassName}");
    }
    return type;
}

代码测试:

Type type = Generate(userClassDesc);
dynamic user = Activator.CreateInstance(type, null);           
user.Name = "mj";
user.Age = 18;
posted @   二次元攻城狮  阅读(39)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
  1. 1 烟花易冷 小柔Channel
  2. 2 红颜如霜 江壹纯
  3. 3 不谓侠 小桃Channel
  4. 4 小小恋歌 新坦结衣
  5. 5 神预言 袁娅维TIARAY
烟花易冷 - 小柔Channel
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.
点击右上角即可分享
微信分享提示
主题色彩