问题描述
在 PowerShell 模块或脚本文件中指定 using namespace
时,是否存在与引入命名空间符号的指令关联的范围?
还是将命名空间符号引入全局会话状态以避免 PS 范围修饰符?
using namespace System.Management.Automation.Runspaces
例如,如果我们在模块内指定 using namespace
,如果这仅适用于模块范围,那就太好了。
同样,如果我们在脚本文件中指定 using namespace
,如果这仅适用于该脚本,除非点源。
我没有对此进行任何测试,也无法找到有关此问题的文档。
解决方法
using namespace
语句遵循 PowerShell 通常的动态范围规则[1]:
-
它在它所在的作用域以及所有后代作用域中生效。
- 如果脚本文件 (
*.ps1
) 为 dot-sourced(例如. ./file.ps1
),则该语句在调用方范围内生效。
- 如果脚本文件 (
-
由于模块有自己的作用域域(“会话状态”),它们只连接到全局作用域,模块中的
using namespace
语句不会影响任何模块外部调用者。-
警告:从 PowerShell 7.1 开始,您不能使用依赖于
using namespace
语句的纯名称类型文字(例如,[System.Management.Automation.Runspaces.Command]
的[Command]
)在导出函数的[OutputType([...])]
属性中(它们在参数声明和函数体中工作正常),如您发现的 GitHub 问题 GitHub issue #13768 中所述。
-
警告:从 PowerShell 7.1 开始,您不能使用依赖于
[1] 在撰写本文时,概念性的 about_Scopes 帮助主题并未明确讨论 PowerShell 范围的动态性质本身(与您在 C# 等语言中会发现的 词法 范围不同)。简单来说,PowerShell 的动态范围意味着,在给定的范围域内(非模块代码与给定模块的代码),从给定调用方调用的代码受该调用方运行时状态的影响,例如通过 using
语句、Set-StrictMode
设置以及调用方变量的可见性。