Roslyn 脚本 - 使用别名
Roslyn scripting - using aliases
我刚刚开始使用 Roslyn 脚本,我在理解 ScriptOptions
class 上的 Imports
属性 时遇到了一些问题作品。我对导入整个命名空间的概念很满意,但是如果我将单个 class 名称添加到导入列表中,如果不完全限定它们,我就无法在我的脚本中使用它们。例如:
错误:"CS0103: The name 'DateTime' does not exist in the current context"
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 似乎暗示名称空间、静态 classes 和别名都可以导入。我是在做傻事还是漏掉了一些明显的东西?
更新
感谢Enfyve的帮助评论,我现在可以访问静态属性和方法,但在调用构造函数时我仍然必须使用完全限定名称:
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();
您可以通过导入来访问类型的静态属性和方法就好像它是一个别名一样。例如:使用 .WithImports("System.DateTime")
然后 "UtcNow"
然而,这不是真实的 type-alias-directive(参见:Issue #7451)
因此您不能以这种方式创建对象。
我刚刚开始使用 Roslyn 脚本,我在理解 ScriptOptions
class 上的 Imports
属性 时遇到了一些问题作品。我对导入整个命名空间的概念很满意,但是如果我将单个 class 名称添加到导入列表中,如果不完全限定它们,我就无法在我的脚本中使用它们。例如:
错误:"CS0103: The name 'DateTime' does not exist in the current context"
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 似乎暗示名称空间、静态 classes 和别名都可以导入。我是在做傻事还是漏掉了一些明显的东西?
更新
感谢Enfyve的帮助评论,我现在可以访问静态属性和方法,但在调用构造函数时我仍然必须使用完全限定名称:
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();
您可以通过导入来访问类型的静态属性和方法就好像它是一个别名一样。例如:使用 .WithImports("System.DateTime")
然后 "UtcNow"
然而,这不是真实的 type-alias-directive(参见:Issue #7451) 因此您不能以这种方式创建对象。