所以我试图使用Roslyn创建一个动态类型(在运行时)。这个要求的整个背景太长了,无法进入。但是,我确实需要创建一个具有x个属性的新类型,我试图在字典中输入属性名称和初始值
以下是相关代码
private void CreateAssembly(Dictionary<string, string> propertiesToEmit)
{
if (ourAssembly == null)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("using System;");
sb.AppendLine("public class MyClass");
sb.AppendLine("{");
sb.AppendLine(" public static void Main()");
sb.AppendLine(" {");
sb.AppendLine(" }");
foreach (var kvp in propertiesToEmit)
{
sb.AppendLine($" public {kvp.Value} {kvp.Key}" + " { get; set; }");
}
sb.AppendLine(" public MyClass CreateFromDynamic(Dictionary<string, object> sourceItem)");
sb.AppendLine(" {");
sb.AppendLine(" MyClass newOne = new MyClass();");
foreach (var kvp in propertiesToEmit)
{
sb.AppendLine($@" newOne.{kvp.Key} = sourceItem[""{kvp.Key}""];");
}
sb.AppendLine(" return newOne;");
sb.AppendLine(" }");
sb.AppendLine("}");
var tree = CSharpSyntaxTree.ParseText(sb.ToString());
var mscorlib = MetadataReference.CreateFromFile(typeof(object).Assembly.Location);
var dictsLib = MetadataReference.CreateFromFile(typeof(Dictionary<,>).Assembly.Location);
var compilation = CSharpCompilation.Create("MyCompilation",
syntaxTrees: new[] { tree }, references: new[] { mscorlib, dictsLib });
//Emit to stream
var ms = new MemoryStream();
var emitResult = compilation.Emit(ms);
//Load into currently running assembly. Normally we'd probably
//want to do this in an AppDomain
ourAssembly = Assembly.Load(ms.ToArray());
}
}
我在Roslyn中遇到这个奇怪的错误,它似乎无法找到对Dictionary&lt;,&gt;的引用。即使这是在 mscorlib 中引用的。
可以清楚地看到Dictionary&lt;,&gt;确实存在于被引用的dll(即 mscorlib )中。
有什么想法吗?
答案 0 :(得分:1)
好的我找到了答案,我忘了在使用Roslyn创建的代码中添加这个using语句
sb.AppendLine("using System.Collections.Generic;");