示例中给出的代码完美地起作用.但是,如果我使用Console.ReadKey(),它会给我错误CS0117:’Console’不包含’ReadKey’的定义.我在某处读到这是因为dotnet核心不支持ReadKey(‘Console’ does not contain a definition for ‘ReadKey’ in asp.net 5 console App),但我目前正在使用“Microsoft.NETCore.App”,如果我在代码中显式使用它而不是使用Roslyn,则Console.ReadKey()可以正常工作.
>这是罗斯林的问题还是我做错了什么?
>“Microsoft.NETCore.App”和dotnet核心是一回事吗?我怀疑我可能正在使用其他东西作为我的目标(允许我使用ReadKey)和dotnet核心与Roslyn
>是否有可能将罗斯林的目标改为其他目标?
提前致谢.
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.Loader; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Emit; namespace DemoCompiler { class Program { public static void roslynCompile() { string code = @" using System; using System.Text; namespace RoslynCompileSample { public class Writer { public void Write(string message) { Console.WriteLine(message); Console.ReadKey(); } } }"; SyntaxTree SyntaxTree = CSharpSyntaxTree.ParseText(code); string assemblyName = Path.GetRandomFileName(); MetadataReference[] references = new MetadataReference[] { MetadataReference.CreateFromFile(typeof(object).GetTypeInfo().Assembly.Location),MetadataReference.CreateFromFile(typeof(Enumerable).GetTypeInfo().Assembly.Location) }; 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.Error.WriteLine("{0}: {1}",diagnostic.Id,diagnostic.GetMessage()); } else { ms.Seek(0,SeekOrigin.Begin); Assembly assembly = AssemblyLoadContext.Default.LoadFromStream(ms); var type= assembly.GetType("RoslynCompileSample.Writer"); var instance = assembly.CreateInstance("RoslynCompileSample.Writer"); var meth = type.GetMember("Write").First() as MethodInfo; meth.Invoke(instance,new [] {assemblyName}); } } } } }
编辑:我试图引用System.Console.dll,但我和System.Private.CoreLib之间发生冲突.我该如何解决?
解决方法
@H_502_24@ 一种方法是将< PreserveCompilationContext> true< / PreserveCompilationContext> *添加到项目文件中,然后使用Microsoft.Extensions.DependencyModel.DependencyContext获取当前项目的所有参考程序集:var references = DependencyContext.Default.CompileLibraries .SelectMany(l => l.ResolveReferencePaths()) .Select(l => MetadataReference.CreateFromFile(l));
这似乎可以避免您获得的错误,但会导致以下警告:
warning CS1701: Assuming assembly reference ‘System.Runtime,Version=4.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a’ used by ‘System.Console’ matches identity ‘System.Runtime,Version=4.1.0.0,PublicKeyToken=b03f5f7f11d50a3a’ of ‘System.Runtime’,you may need to supply runtime policy
As far as I can tell,this should not be an issue.
*这假设您正在使用csproj / VS2017.如果您仍在使用project.json / VS2015,则可以使用“buildOptions”完成相同的操作:{“preserveCompilationContext”:true}.