.NET Core 上的 Roslyn 脚本 API:为什么编译器会抱怨 "error CS1501: no overload for WriteLine takes 2 arguments"?
Roslyn Scripting API on .NET Core: why does compiler complain "error CS1501: no overload for WriteLine takes 2 arguments"?
我正在 OSX 上开发一个针对 netcoreapp1.0
的项目,我正在使用 Roslyn 设置脚本,如下所示:
var scriptText = File.ReadAllText(args[0]);
var scriptOptions = ScriptOptions.Default
.WithReferences(
typeof(System.Object).GetTypeInfo().Assembly
);
var script = CSharpScript.Create(scriptText, scriptOptions, typeof(Globals));
var scriptArgs = new string[args.Length-1];
Array.Copy(args, 1, scriptArgs, 0, args.Length-1);
script.RunAsync(new Globals
{
Args = scriptArgs
})
.GetAwaiter().GetResult();
其中 Globals
是:
public class Globals
{
public string[] Args { get; set; }
}
当我尝试 运行 如下所示的脚本时:
using System;
Console.WriteLine("Args[0]: {0}", Args[0]);
程序因以下异常而终止:
$ dotnet run test.csx
Project BitThicket.DotNet.ScriptTool (.NETCoreApp,Version=v1.0) was previously compiled. Skipping compilation.
Script error: Microsoft.CodeAnalysis.Scripting.CompilationErrorException: (7,9): error CS1501: No overload for method 'WriteLine' takes 2 arguments
at Microsoft.CodeAnalysis.Scripting.ScriptBuilder.ThrowIfAnyCompilationErrors(DiagnosticBag diagnostics, DiagnosticFormatter formatter)
at Microsoft.CodeAnalysis.Scripting.ScriptBuilder.CreateExecutor[T](ScriptCompiler compiler, Compilation compilation, CancellationToken cancellationToken)
at Microsoft.CodeAnalysis.Scripting.Script`1.GetExecutor(CancellationToken cancellationToken)
at Microsoft.CodeAnalysis.Scripting.Script`1.RunAsync(Object globals, Func`2 catchException, CancellationToken cancellationToken)
at BitThicket.DotNet.ScriptTool.Program.Main(String[] args) in /Users/ben/proj/bt/dotnet-scriptcs/src/BitThicket.DotNet.ScriptTool/Program.cs:line 63
显然 Console
实际上有一个采用 2 个方法的重载。我简要地查看了 CoreFx sources 以查看是否使用了任何奇怪的类型转发或扩展方法技巧,这些技巧可能需要在脚本设置中额外注意,但我没有看到任何不寻常的地方(也许我错过了一些东西).
为什么 Roslyn ScriptBuilder
会抱怨这个?
在 .NET Core 中,Console
class 在 System.Console
程序集中,因此您需要将其添加到脚本的引用中:
var scriptOptions = ScriptOptions.Default
.WithReferences(
typeof(System.Object).GetTypeInfo().Assembly,
typeof(System.Console).GetTypeInfo().Assembly
);
如果您检查 Object
的装配位置,您会看到它是 System.Private.CoreLib.ni.dll
。使用 ILSpy,我们可以看到这个程序集只包含一个基本的 Console
实现,方法有 Write(string s)
、WriteLine(string s)
和 WriteLine()
。而 System.Console
程序集包含完整的实现。
我正在 OSX 上开发一个针对 netcoreapp1.0
的项目,我正在使用 Roslyn 设置脚本,如下所示:
var scriptText = File.ReadAllText(args[0]);
var scriptOptions = ScriptOptions.Default
.WithReferences(
typeof(System.Object).GetTypeInfo().Assembly
);
var script = CSharpScript.Create(scriptText, scriptOptions, typeof(Globals));
var scriptArgs = new string[args.Length-1];
Array.Copy(args, 1, scriptArgs, 0, args.Length-1);
script.RunAsync(new Globals
{
Args = scriptArgs
})
.GetAwaiter().GetResult();
其中 Globals
是:
public class Globals
{
public string[] Args { get; set; }
}
当我尝试 运行 如下所示的脚本时:
using System;
Console.WriteLine("Args[0]: {0}", Args[0]);
程序因以下异常而终止:
$ dotnet run test.csx
Project BitThicket.DotNet.ScriptTool (.NETCoreApp,Version=v1.0) was previously compiled. Skipping compilation.
Script error: Microsoft.CodeAnalysis.Scripting.CompilationErrorException: (7,9): error CS1501: No overload for method 'WriteLine' takes 2 arguments
at Microsoft.CodeAnalysis.Scripting.ScriptBuilder.ThrowIfAnyCompilationErrors(DiagnosticBag diagnostics, DiagnosticFormatter formatter)
at Microsoft.CodeAnalysis.Scripting.ScriptBuilder.CreateExecutor[T](ScriptCompiler compiler, Compilation compilation, CancellationToken cancellationToken)
at Microsoft.CodeAnalysis.Scripting.Script`1.GetExecutor(CancellationToken cancellationToken)
at Microsoft.CodeAnalysis.Scripting.Script`1.RunAsync(Object globals, Func`2 catchException, CancellationToken cancellationToken)
at BitThicket.DotNet.ScriptTool.Program.Main(String[] args) in /Users/ben/proj/bt/dotnet-scriptcs/src/BitThicket.DotNet.ScriptTool/Program.cs:line 63
显然 Console
实际上有一个采用 2 个方法的重载。我简要地查看了 CoreFx sources 以查看是否使用了任何奇怪的类型转发或扩展方法技巧,这些技巧可能需要在脚本设置中额外注意,但我没有看到任何不寻常的地方(也许我错过了一些东西).
为什么 Roslyn ScriptBuilder
会抱怨这个?
在 .NET Core 中,Console
class 在 System.Console
程序集中,因此您需要将其添加到脚本的引用中:
var scriptOptions = ScriptOptions.Default
.WithReferences(
typeof(System.Object).GetTypeInfo().Assembly,
typeof(System.Console).GetTypeInfo().Assembly
);
如果您检查 Object
的装配位置,您会看到它是 System.Private.CoreLib.ni.dll
。使用 ILSpy,我们可以看到这个程序集只包含一个基本的 Console
实现,方法有 Write(string s)
、WriteLine(string s)
和 WriteLine()
。而 System.Console
程序集包含完整的实现。