【发布时间】:2017-06-16 13:21:32
【问题描述】:
我刚刚开始使用 Roslyn 脚本,在理解 ScriptOptions 类上的 Imports 属性的工作方式时遇到了一些问题。我对导入整个命名空间的概念很好,但是如果我将单个类名添加到导入列表中,如果没有完全限定它们,我就不能在我的脚本中使用它们。例如:
错误:“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 似乎建议命名空间、静态类和别名都可以导入。我是在做一些愚蠢的事情还是在这里遗漏了什么明显的东西?
更新
感谢Enfyve 的帮助 cmets,我现在可以访问静态属性和方法,但在调用构造函数时我仍然必须使用完全限定名称:
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();
【问题讨论】:
-
在您的
WithReferences和WithImports中使用typeof(System.DateTime)...代替 -
谢谢,但
WithImports仅具有接受IEnumerable<string>和params string[]的重载,因此我无法传入Type。 github.com/dotnet/roslyn/blob/master/src/Scripting/Core/… -
我的意思是代替
typeof(DateTime).Assembly做typeof(System.DateTime).Assembly -
您好,再次感谢,但获取程序集引用不是问题;
typeof(DateTime).Assembly正确地给了我对mscorlib的引用。typeof(System.DateTime).Assembly给出相同的结果(这是意料之中的,因为我的托管脚本引擎的代码在代码中有using System;语句)。问题是在我的导入中添加"System.DateTime"需要我在脚本中完全限定DateTime,而在我的导入中添加"System"使脚本可以访问整个System命名空间,而不仅仅是@987654355 @. -
对不起,我的摇摆不定 - 我责怪睡眠不足。您可以在导入中包含类型别名(形象地说)。它是
.WithImports("System.DateTime"),然后在脚本中使用UtcNow。 (这同样适用于System.Math和Sqrt()之类的东西,但考虑到 Sqrt() 是静态方法而不是静态属性,后者更直观)。