[转]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;

浙公网安备 33010602011771号