2017-01-31 10 views
1

Я только начинаю с создания сценариев Roslyn, и у меня есть немного проблем с пониманием того, как работает Imports на классе ScriptOptions. Я в порядке с концепцией импорта целого пространства имен, но если я добавлю отдельные имена классов в список импорта, я не смогу использовать их в своем скрипте, не полностью квалифицируя их. Например:Сценарии Roslyn - используя псевдонимы

Ошибка: "CS0103: Имя 'DateTime' не существует в текущем контексте"

var scriptOptions = ScriptOptions.Default 
           .WithReferences(typeof(DateTime).Assembly) 
           .WithImports(typeof(DateTime).FullName); 

var script = CSharpScript.Create<DateTime>("DateTime.UtcNow", 
              scriptOptions); 

var now = script.RunAsync(null, CancellationToken.None).Result; 

успеха: Используйте Полностью Квалифицированные Тип Название

var scriptOptions = ScriptOptions.Default 
           .WithReferences(typeof(DateTime).Assembly) 
           .WithImports(typeof(DateTime).FullName); 

var script = CSharpScript.Create<DateTime>("System.DateTime.UtcNow", 
              scriptOptions); 

var now = script.RunAsync(null, CancellationToken.None).Result; 

Успех: Импорт в системное пространство имён

var scriptOptions = ScriptOptions.Default 
           .WithReferences(typeof(DateTime).Assembly) 
           .WithImports("System"); 

var script = CSharpScript.Create<DateTime>("DateTime.UtcNow", 
              scriptOptions); 

var now = script.RunAsync(null, CancellationToken.None).Result; 

Что я хотел бы сделать, это ограничить скрипт так, чтобы он имел доступ только к нескольким типам в пространстве имен (т. Я не хочу, чтобы все пространство пространства System было доступно, но разрешено доступ к System.DateTime, System.Math и т. Д.), Но не требует, чтобы скрипт полностью квалифицировал эти имена типов, когда они используются. Я понимаю, что также можно добавить инструкции using к самому скрипту, но мне бы хотелось, чтобы механизм сценариев позаботился об этом для меня.

Я попытался объявить псевдонимы в методе WithImports (например, ScriptOptions.Default.WithImports("DateTime = System.DateTime")), но это просто дает мне ошибку компиляции (CS0246: The type or namespace name 'DateTime = System' could not be found (are you missing a using directive or an assembly reference?)).

Документация кажется довольно тонкой на земле, но source for the ScriptImports class, по-видимому, предполагает, что все пространства имен, статические классы и псевдонимы могут быть импортированы. Я делаю что-то глупое или отсутствует что-то очевидное здесь?

UPDATE

Благодаря полезные комментарии Enfyve «s, теперь я могу получить доступ к статическим свойствам и методам, но я до сих пор использовать полное имя при вызове конструктора:

var scriptOptions = ScriptOptions.Default 
           .WithReferences(typeof(System.DateTime).FullName) 
           .WithImports("System.DateTime"); 

var script = CSharpScript.Create<object>("new DateTime()", scriptOptions); 

// Still throws CS0246 compiler error... 
var result = script.RunAsync(null, CancellationToken.None).Result.Dump(); 
+0

В ваших 'WithReferences' и' WithImports' используйте 'typeof (System.DateTime) ...' вместо – Enfyve

+0

Спасибо, но 'WithImports' имеет только перегрузки, которые принимают' IEnumerable 'и' params string [] ', поэтому Я не могу передать «Тип». https://github.com/dotnet/roslyn/blob/master/src/Scripting/Core/ScriptOptions.cs#L262 –

+0

Я имею в виду вместо 'typeof (DateTime) .Assembly' do' typeof (System.DateTime) .Assembly' – Enfyve

ответ

0

Вы можете получить доступ к статическим свойствам и методам типа, импортировав его , как если бы это был псевдоним. например: с .WithImports("System.DateTime"), а затем "UtcNow"

Однако это не является истинным типа псевдоним директивы (см: Issue #7451) и поэтому вы не можете создавать объекты в этой манере.