我有一个无法解决的奇怪问题。我大部分时间都在成功编译动态程序集,但在编译以下行时遇到了一个奇怪的问题:
返回新的 JObject().Properties().ElementAt(0).Value();
出现错误:
System.ApplicationException: 'Error creating dynamic code assembly 'IEnumerable<JProperty>' does not contain a definition for 'ElementAt' and no accessible extension method 'ElementAt' accepting a first argument of type 'IEnumerable<JProperty>' could be found (are you missing a using directive or an assembly reference?) '
当在项目中创建为真实类时,发出的文本输出可以正常工作,但在动态程序集中则不行。该项目是一个 asp.net core 2.2 项目,它引用了一个创建动态程序集的程序集。
这是创建程序集的代码:
public static class Class2
{
public static Assembly GenerateAssenbly()
{
//generate the code
StringBuilder sb = new StringBuilder("");
sb.AppendLine("using System;");
sb.AppendLine("using System.Linq;");
sb.AppendLine("using Newtonsoft.Json;");
sb.AppendLine("using Newtonsoft.Json.Linq;");
sb.AppendLine("namespace test");
sb.AppendLine("{");
sb.AppendLine($"class Parser");
sb.AppendLine("{");
sb.AppendLine($"public object test() ");
sb.AppendLine("{");
sb.AppendLine("return new JObject().Properties().ElementAt(0).Value<string>();");
sb.AppendLine("}");
sb.AppendLine("}"); //class
sb.AppendLine("}"); //namespace
SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(sb.ToString());
var runtimeAssemblyDirectory = Path.GetDirectoryName(typeof(object).Assembly.Location);
string assemblyName = Path.GetRandomFileName();
MetadataReference[] references = new MetadataReference[]
{
MetadataReference.CreateFromFile(typeof(object).GetTypeInfo().Assembly.Location),
MetadataReference.CreateFromFile(Assembly.GetExecutingAssembly().Location),
MetadataReference.CreateFromFile(Path.Combine(runtimeAssemblyDirectory, "System.Runtime.dll")),
MetadataReference.CreateFromFile(Path.Combine(runtimeAssemblyDirectory, "mscorlib.dll")),
MetadataReference.CreateFromFile(Path.Combine(runtimeAssemblyDirectory, "System.dll")),
MetadataReference.CreateFromFile(Path.Combine(runtimeAssemblyDirectory, "netstandard.dll")),
MetadataReference.CreateFromFile(Path.Combine(runtimeAssemblyDirectory, "System.Core.dll")),
MetadataReference.CreateFromFile(typeof(JObject).GetTypeInfo().Assembly.Location),
};
CSharpCompilation compilation = CSharpCompilation.Create(
assemblyName,
syntaxTrees: new[] { syntaxTree },
references: references,
options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
Debug.Print(sb.ToString()); // copy output to a class to test
using (var ms = new MemoryStream())
{
EmitResult result = compilation.Emit(ms);
if (!result.Success)
{
throw new ApplicationException($"Error creating dynamic code assembly " + GetCompilerResultsErrors(result));
}
else
{
return Assembly.Load(ms.GetBuffer());
}
}
}
private static string GetCompilerResultsErrors(EmitResult result)
{
StringBuilder sb = new StringBuilder();
IEnumerable<Diagnostic> failures = result.Diagnostics.Where(diagnostic =>
diagnostic.IsWarningAsError ||
diagnostic.Severity == DiagnosticSeverity.Error);
foreach (Diagnostic diagnostic in failures)
{
sb.AppendLine(diagnostic.GetMessage());
}
return sb.ToString();
}
}
(显示的代码不用于工作目的,它被简化以演示问题)
提前致谢,