The following program attempts to compile and execute a script of C#. However, I keep getting the output:
CS0103: The name 'Queryable' does not exist in the current context
CS1061: 'int[]' does not contain a definition for 'AsQueryable' and no accessible extension method 'AsQueryable' accepting a first argument of type 'int[]' could be found (are you missing a using directive or an assembly reference?)
Which assembly am I missing in refPaths? I assumed [System.Linq] would be all I need, which I then added through [typeof(Enumerable).GetTypeInfo().Assembly.Location].
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Loader;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Emit;
namespace CompileScript
{
class Program
{
static async Task Main(string[] args)
{
string script = @"using System;
using System.Linq;
namespace Test { class Program {
public static void Main() {
Console.WriteLine(""Testing a script..."");
int[] arr = new int[] { 1, 2, 3};
double avg = Queryable.Average(arr.AsQueryable());
Console.WriteLine(""Average = "" + avg);}}}";
var refPaths = new[] {
typeof(object).GetTypeInfo().Assembly.Location,
typeof(Console).GetTypeInfo().Assembly.Location,
typeof(Enumerable).GetTypeInfo().Assembly.Location,
Path.Combine(Path.GetDirectoryName
(typeof(System.Runtime.GCSettings).
GetTypeInfo().Assembly.Location), "System.Runtime.dll"),
};
SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(script);
string assemblyName = Path.GetRandomFileName();
MetadataReference[] references = refPaths.Select(r => MetadataReference.
CreateFromFile(r)).ToArray();
CSharpCompilation compilation = CSharpCompilation.Create(
assemblyName,
syntaxTrees: new[] { syntaxTree },
references: references,
options: new CSharpCompilationOptions
(OutputKind.DynamicallyLinkedLibrary));
using var ms = new MemoryStream();
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.WriteLine("\t{0}: {1}", diagnostic.Id,
diagnostic.GetMessage());
}
}
else
{
ms.Seek(0, SeekOrigin.Begin);
Assembly assembly = AssemblyLoadContext.Default.LoadFromStream(ms);
var type = assembly.GetType("Test.Program");
var instance = assembly.CreateInstance("Test.Program");
MethodInfo? methodInfo = type.GetMethod("Main");
methodInfo.Invoke(instance, null);
}
}
}
}
Aucun commentaire:
Enregistrer un commentaire