2016-07-28 10 views
5

pracuję nad projektem kierowania netcoreapp1.0 na OSX, a ja stworzenie skryptu przy użyciu Roslyn tak:Roslyn Scripting API na .NET Core: dlaczego kompilator narzeka "błąd CS1501: żadne przeciążenie dla WriteLine nie wymaga 2 argumentów"?

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(); 

Gdzie Globals jest:

public class Globals 
{ 
    public string[] Args { get; set; } 
} 

Kiedy próbuję uruchomić skrypt, który wygląda tak:

using System; 

Console.WriteLine("Args[0]: {0}", Args[0]); 

Program kończy się z tego wyjątku:

$ 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 

Oczywiście w rzeczywistości mamy przeciążenie, które wymaga 2 metod. Spojrzałem krótko na numer CoreFx sources, aby sprawdzić, czy istnieją jakieś dziwne sztuczki przekazywania lub rozszerzenia, które mogą wymagać dodatkowej opieki w konfiguracji skryptu, ale nie zauważyłem tam niczego niezwykłego (może coś mi umknęło).

Dlaczego na przykład Roslyn ScriptBuilder narzekał?

+0

Co się dzieje, gdy używasz nowego stylu formatowania? tj. 'Console.WriteLine ($" Args [0]: {Args [0]} ");' – PhillipXT

+0

Dzięki za sugestię @PhillipXT. Działa ze składnią interpolacji napisów, ale jest to rodzaj paperingu nad leżącym u jej podstaw problemem - skrypt faktycznie robi coś więcej niż tylko "Console.WriteLine", ale mam do czynienia z pewnymi błędami związanymi z odwołaniami do zestawu. Miejmy nadzieję, że znalezienie prawdziwego problemu pomoże ci znaleźć drogę do innych problemów. –

+1

Chciałem tylko sprawdzić i upewnić się, że Args [0] nie był jakoś problemem. Nie jestem pewien, co jeszcze może być nie tak z WriteLine ... – PhillipXT

Odpowiedz

6

w .NET Core klasa Console jest w zespole System.Console, więc trzeba go dodać do odniesień do skryptu:

var scriptOptions = ScriptOptions.Default 
    .WithReferences(
     typeof(System.Object).GetTypeInfo().Assembly, 
     typeof(System.Console).GetTypeInfo().Assembly 
    ); 

Jeśli sprawdzić lokalizację montażowej Object, będziesz zobacz, czy to System.Private.CoreLib.ni.dll. Korzystając z ILSpy, widzimy, że ten zestaw zawiera tylko podstawową implementację Console, przy użyciu metod Write(string s),i . Podczas gdy zestaw System.Console zawiera pełną implementację.

+0

Nie jestem na moim komputerze, aby spróbować w tej chwili, ale jeśli tak jest, dlaczego więc kompilator nie znalazłby w moim przykładzie typu 'Console'? –

+0

@BenCollins Masz rację, to dziwne. Ale dodanie zespołu działa, sprawdziłem. –

+1

@BenCollins Zaktualizowałem swoją odpowiedź z wyjaśnieniem. –

Powiązane problemy