【问题标题】:Roslyn scripting - using aliasesRoslyn 脚本 - 使用别名
【发布时间】: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.DateTimeSystem.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();

【问题讨论】:

  • 在您的WithReferencesWithImports 中使用typeof(System.DateTime)... 代替
  • 谢谢,但WithImports 仅具有接受IEnumerable&lt;string&gt;params string[] 的重载,因此我无法传入Typegithub.com/dotnet/roslyn/blob/master/src/Scripting/Core/…
  • 我的意思是代替typeof(DateTime).Assemblytypeof(System.DateTime).Assembly
  • 您好,再次感谢,但获取程序集引用不是问题; typeof(DateTime).Assembly 正确地给了我对 mscorlib 的引用。 typeof(System.DateTime).Assembly 给出相同的结果(这是意料之中的,因为我的托管脚本引擎的代码在代码中有 using System; 语句)。问题是在我的导入中添加"System.DateTime" 需要我在脚本中完全限定DateTime,而在我的导入中添加"System" 使脚本可以访问整个System 命名空间,而不仅仅是@987654355 @.
  • 对不起,我的摇摆不定 - 我责怪睡眠不足。您可以在导入中包含类型别名(形象地说)。它是.WithImports("System.DateTime"),然后在脚本中使用UtcNow。 (这同样适用于 System.MathSqrt() 之类的东西,但考虑到 Sqrt() 是静态方法而不是静态属性,后者更直观)。

标签: c# scripting roslyn


【解决方案1】:

您可以通过将其导入如同它是别名来访问该类型的静态属性和方法。例如:.WithImports("System.DateTime") 然后"UtcNow"

但是,这不是真正的 type-alias-directive(请参阅:Issue #7451) 所以你不能以这种方式创建对象。

【讨论】:

    猜你喜欢
    • 2018-03-10
    • 1970-01-01
    • 1970-01-01
    • 2016-07-06
    • 2016-02-18
    • 2013-11-25
    • 1970-01-01
    • 1970-01-01
    • 2016-12-16
    相关资源
    最近更新 更多