[转]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;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!