在特殊情况下,需要根据场景情况动态创建c#代码,然后在运用里调用并执行动态生成的类对象。这里提供动态编译代码的方法及使用案例,以供大家学习及参考,如有任何疑问可留言。
string code = File.ReadAllText("D:\\UserInfo.cs"); //获取cs文件,C#代码
Assembly assembly = GenerateAssemblyFromCode(code); //编译并获取到对应的程序集
Type type = assembly.GetType("UserInfo"); //在获取到的程序集里获取 UserInfo 类型
UserInfo userInfo = (UserInfo)Activator.CreateInstance(type); //使用获取到的类型来创建对象实例
string UserName = userInfo.name;
附:D:\\UserInfo.cs 文件
using System;
public class UserInfo
{
public Guid id { get; set; }
public string name { get; set; }
public int age { get; set; }
public string address { get; set; }
public DateTime cdatetime { get; set; }
}
/// <summary>
/// 动态编译
/// </summary>
/// <param name="code">需要动态编译的代码</param>
/// <returns>动态生成的程序集</returns>
public static Assembly GenerateAssemblyFromCode(string code)
{
Assembly asse = null;
Assembly[] asses = AppDomain.CurrentDomain.GetAssemblies();
List<MetadataReference> metadataReferences = new List<MetadataReference>();
foreach (var item in asses)
{
if (string.IsNullOrEmpty(item.Location)) continue;
metadataReferences.Add(MetadataReference.CreateFromFile(item.Location));
}
var references1 = metadataReferences.ToArray(); //asses.Select(x => MetadataReference.CreateFromFile(x.Location));
// 随机程序集名称
string assemblyName = Path.GetRandomFileName();
SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(code);
// 创建编译对象
CSharpCompilation compilation = CSharpCompilation.Create(
assemblyName,
syntaxTrees: new[] { syntaxTree },
references: references1,
options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
using (var ms = new MemoryStream())
{
// 将编译后的IL代码放入内存中
EmitResult result = compilation.Emit(ms);
// 编译失败,提示
if (!result.Success)
{
IEnumerable<Diagnostic> failures = result.Diagnostics.Where(diagnostic =>
diagnostic.IsWarningAsError ||
diagnostic.Severity == DiagnosticSeverity.Error);
foreach (Diagnostic diagnostic in failures)
{
//Console.Error.WriteLine("{0}: {1}", diagnostic.Id, diagnostic.GetMessage());
err += string.Format("{0}: {1}", diagnostic.Id, diagnostic.GetMessage())+"\r\n";
}
}
else
{
// 编译成功则从内存中加载程序集
ms.Seek(0, SeekOrigin.Begin);
asse = Assembly.Load(ms.ToArray());
}
}
return asse;
}