编辑说明
重要
Windows PowerShell 语言规范 3.0 于 2012 年 12 月发布,基于 Windows PowerShell 3.0。 此规范不反映 PowerShell 的当前状态。 没有计划更新本文档以反映当前状态。 此处提供了本文档供历史参考。
该规范文档可作为 Microsoft Word 文档从 Microsoft 下载中心获取:https://www.microsoft.com/download/details.aspx?id=36389 该 Word 文档已在此 Microsoft Learn 上转换为展示形式。 转换期间,进行了一些编辑更改,以适应 Docs 平台的格式设置。 已更正某些拼写错误和次要错误。
当某种类型的值用于需要不同类型的上下文时,将执行类型转换。 如果此类转换自动发生,则称为 隐式转换。 (一个常见的示例是,某些运算符需要转换其操作数指定的一个或多个值。允许隐式转换,前提是保留源值的感觉,例如在转换数字时不会丢失数字的精度。
强制转换运算符 (§7.2.9) 允许显式转换。
下面将讨论转换,并在必要时在 §6.19中对每个运算符的说明提供补充信息。
将值显式转换为它已具有的类型不会更改该值或其表示形式。
当表达式的值绑定到某个参数时,§6.17 中介绍了手动转换的规则。
6.1 转换为 void
可以通过将任何类型的值强制转换为 void 类型来显式丢弃该值。 没有结果。
6.2 转换为布尔
将任何值转换为布尔类型的规则如下所示:
- 数值或字符值为零时,转换为 False;非零的数值或字符值则转换为 True。
- 空类型的值转换为假。
- 长度为 0 的字符串转换为 False;长度 > 0 的字符串转换为 True。
- 具有值
$true
的开关参数将转换为 True,具有值$false
的开关参数转换为 False。 - 所有其他非 null 引用类型值都转换为 True。
如果类型实现了 IList:
- 如果对象的长度为 > 2,该值将转换为 True。
- 如果对象的 Length 为 1,并且第一个元素本身不是 IList,则如果该元素的值为 true,则该值将转换为 True。
- 否则,如果第一个元素的 Count >= 1,该值将转换为 True。
- 否则,该值将转换为 False。
6.3 转换为 char
将任何值转换为类型 char 的规则如下所示:
- 布尔、小数、浮点数或双标量类型的值的转换出错。
- null 类型的值将转换为 null (U+0000) 字符。
- 一个整数类型值,如果其值可以用 char 类型表示,则该整数取该值,否则转换出错。
- 长度不是 1 的字符串值在转换时出错。
- 长度为 1 的字符串值转换为具有该字符值的字符。
- 一个数值类型值,其舍入任何小数部分后的值可以在目标类型中表示该舍入值;否则,转换出错。
- 对于其他引用类型值,如果引用类型支持此类转换,则使用该转换;否则,转换出错。
6.4 转换为整数
将任何值转换为字节、int 或 long 类型的规则如下所示:
- 布尔值 False 转换为零;布尔值 True 转换为 1。
- 一个字符类型的值,如果其值可以在目标类型中表示,则采用该值;否则,转换会出错。
- 一个数值类型值,其舍入任何小数部分后的值可以在目标类型中表示该舍入值;否则,转换出错。
- null 类型的值转换为零。
- 如 §6.16中所述,一个表示数字的字符串被转换。 如果在截断小数部分后,结果可以用目标类型表示,则该字符串格式正确,并且具有目标类型;否则,转换出错。 如果字符串不表示数字,则转换出错。
- 对于其他引用类型值,如果引用类型支持此类转换,则使用该转换;否则,转换出错。
6.5 转换为 float 和 double
将任何值转换为 float 或 double 类型的规则如下所示:
- 布尔值 False 转换为零;布尔值 True 转换为 1。
- char 值得到精确表示。
- 如果可能,数值类型会得到精确表示;但是,对于 int、long 和 decimal 转换为 float,以及 long 和 decimal 转换为 double,整数值的一些最低有效位可能会丢失。
- null 类型的值转换为零。
- 表示数字的字符串,将按照 §6.16中所述进行转换;否则,转换将被视为错误。
- 对于其他引用类型值,如果引用类型支持此类转换,则使用该转换;否则,转换出错。
6.6 转换为十进制
将任何值转换为小数类型的规则如下所示:
- 布尔值 False 转换为零;布尔值 True 转换为 1。
- 字符类型值被准确表示。
- 数字类型值完全表示;但是,如果该值太大或太小,无法适应目标类型,则转换将出错。
- null 类型的值转换为零。
- 一个代表数字的字符串会按照 §6.16中的描述进行转换,否则会发生转换错误。
- 对于其他引用类型值,如果引用类型支持此类转换,则使用该转换;否则,转换出错。
- 成功转换的结果标量使得小数部分没有尾随零。
6.7 转换为对象
除 null 类型(4.1.2)以外的任何类型的值都可以转换为类型对象。 该值保留其类型和表示形式。
6.8 转换为字符串
将任何值转换为类型字符串的规则如下所示:
- 布尔值
$false
转换为“False”;布尔值$true
转换为“True”。 - 字符类型值转换为包含该字符的 1 个字符字符串。
- 数值类型值转换为具有相应数值文本形式的字符串。 但是,结果中没有前导或尾随空格,没有前导加号,整数使用基数 10,并且没有类型后缀。 对于十进制转换,将保留标量。 对于 -∞、+∞ 和 NaN 的值,生成的字符串分别为“-Infinity”、“Infinity”和“NaN”。
- null 类型的值将转换为空字符串。
- 对于一维数组,结果是一个字符串,其中包含该数组中每个元素的值,从头到尾转换为字符串,元素由当前输出字段分隔符分隔(§2.3.2.2)。 对于包含数组自身的数组,仅转换最外层元素。 用于表示数组元素值的字符串是定义的实现。 对于多维数组,它将被平展(§9.12),然后被视为一维数组。
- null 类型的值将转换为空字符串。
- 脚本块类型的值会被转换为一个字符串,其中包含该块的文本,但不包括分隔符 { 和 } 字符。
- 对于枚举类型值,结果是一个字符串,其中包含用逗号分隔的值中编码的每个枚举常量的名称。
- 对于其他引用类型值,如果引用类型支持此类转换,则使用该转换;否则,转换出错。
用于表示数组的元素的值的字符串具有 System.type[]
、System.type[,]
等形式。 对于其他引用类型,将调用方法 ToString
。 对于其他可枚举类型,源值将被视为一个 1 维数组。
6.9 转换为数组
将任何值转换为数组类型的规则如下所示:
- 目标类型可能不是多维数组。
- null 类型的值保持不变。
- 对于除
$null
和哈希表类型的值以外的标量值,将创建一个新的 1 元素数组,其值是该标量转换为目标元素类型后的结果。 - 对于一维数组数值,将创建一个目标类型的新数组,每个元素都通过转换从源数组复制到目标数组中对应的位置。
- 对于多维数组值,该数组首先平展(§9.12),然后被视为一维数组值。
- 字符串值转换为字符数组,其长度相同,字符串中的连续字符占用数组中的相应位置。
对于其他可枚举类型,将创建一个新的 1 元素数组,如果存在此类转换,则创建一个新的 1 元素数组,其值是目标元素类型转换后对应的元素。 否则,转换出错。
6.10 转换为 xml
对象转换为类型字符串,然后转换为 xml
类型的 XML Document 对象。
6.11 转换为正则表达式
指定字符串类型的值的表达式可以转换为类型 regex
。
6.12 转换为 scriptBlock
将任何值转换为类型 scriptblock
的规则如下所示:
- 字符串值被视为命令的名称,后面可选择性地跟随对该命令的调用参数。
6.13 转换为枚举类型
将任何值转换为枚举类型的规则如下所示:
- 一个字符串类型的值,其中包含枚举类型的某个命名值(区分大小写),将被转换为该命名值。
- 一个字符串类型的值包含一个枚举类型的命名值列表,列表内的值用逗号分隔(需考虑大小写),将被转换为所有这些命名值的按位 OR 结果。
6.14 转换为其他引用类型
将任何值转换为数组类型或字符串以外的引用类型的规则如下所示:
- null 类型的值按原样保留。
- 否则,行为是由实现定义的。
在这里涉及多个机制:包括在值为哈希表时,可能使用单参数构造函数或默认构造函数,隐式和显式转换运算符,以及目标类型的 Parse 方法;Convert.ConvertTo 的使用;以及 ETS 转换机制。
6.15 常规算术转换
如果两个操作数都未指定具有数值类型的值,则
- 如果左侧操作数指定布尔类型的值,则转换出错。
- 否则,指定值
$null
的所有操作数将转换为 int 类型的零,然后继续执行下列数值转换。 - 否则,如果左侧操作数指定类型字符的值,而右操作数指定布尔类型的值,则转换将出错。
- 否则,如果左侧操作数指定字符串类型的值,但不表示数字(§6.16),则转换出错。
- 否则,如果右操作数指定字符串类型的值,但不表示数字(§6.16),则转换出错。
- 否则,指定字符串类型值的所有操作数将转换为数字(§6.16),该过程将继续执行下面列出的数值转换。
- 否则,转换出错。
数值转换:
- 如果一个操作数指定小数类型的值,则其他操作数指定的值将在必要时转换为该类型。 结果的类型为十进制。
- 否则,如果一个操作数指定 double 类型的值,则其他操作数指定的值将在必要时转换为该类型。 结果为 double 类型。
- 否则,如果一个操作数指定了 float 类型的值,则两个操作数指定的值将被转换为 double 类型(如有必要)。 结果为 double 类型。
- 否则,如果一个操作数指定了长类型的值,则其他操作数值指定的值将在必要时转换为该类型。 结果是序列中第一个可以表示其值类型,包括 long 和 double。
- 否则,两个操作数指定的值将被转换为整数类型(如果需要)。 结果是序列中第一个可以无损表示其值的类型,包括 int、long、double。
6.16 从字符串转换为数字类型
根据字符串的内容,可以显式或隐式转换为数值。 具体说来
- 空字符串转换为值零。
- 将忽略前导空格和尾随空格;但是,字符串不能仅包含空格。
- 仅包含空格和/或行终止符的字符串将转换为值零。
- 允许使用一个前导 + 或 - 符号。
- 整数可能有十六进制前缀(0x 或 0X)。
- 允许可选带符号的指数。
- 不允许使用类型后缀和乘数。
- 区分大小写的字符串“-Infinity”、“Infinity”和“NaN”分别被识别为值 -∞、+∞ 和 NaN。
6.17 参数绑定期间的转换
有关参数绑定的信息,请参阅 §8.14。
当表达式的值绑定到参数时,需要考虑额外的转换注意事项,如下所示:
- 如果参数类型为 switch(§4.2.5,§8.10.5),并且参数没有参数,则调用命令中的参数值设置为
$true
。 如果参数类型不是 switch,而参数缺少对应的值,则属于错误。 - 如果参数类型为 switch,参数值
$null
,则参数值设置为$false
。 - 如果参数类型为对象或与参数的类型相同,则不进行转换即可传递参数的值。
- 如果参数类型不是对象或 scriptblock,则会计算具有类型 scriptblock 的参数,并将其结果作为参数的值传递。 (这称为 延迟脚本块绑定。)如果参数类型为对象或 scriptblock,则按原样传递具有类型 scriptblock 的参数。
- 如果参数类型是 T2 类型的集合,并且该参数是 T1 类型的标量,则标量将转换为包含一个元素的 T2 类型的集合。 如有必要,使用本部分的转换规则将标量值转换为类型 T2。
- 如果参数类型是对象以外的标量类型,并且参数是集合,则参数出错。
- 如果预期的参数类型是 T2 类型的集合,并且该参数是 T1 类型的集合,则参数将转换为类型 T2 的集合,其长度与参数集合相同。 如有必要,参数集合元素值将使用本节的转换规则转换为类型 T2。
- 如果上述步骤和本章前面指定的转换是不够的,则应用 §6.18 中的规则。 如果失败,参数绑定将失败。
6.18 .NET 转换
对于隐式转换,首先尝试 PowerShell 的内置转换。 如果它们无法解析转换,则尝试从上到下的顺序尝试下面的 .NET 自定义转换器。 如果找到转换却引发异常,则转换失败。
PSTypeConverter:可通过两种方式将 PSTypeConverter 类的实现与其目标类相关联:通过类型配置文件(types.ps1xml)或将
System.ComponentModel.TypeConverterAttribute
属性应用于目标类。 有关详细信息,请参阅 PowerShell SDK 文档。TypeConverter:此 CLR 类型提供将值类型转换为其他类型的统一方法,以及访问标准值和子属性。 最常见的转换器类型是与文本表示形式相互转换的转换器。 类的类型转换器绑定到具有
System.ComponentModel.TypeConverterAttribute
的类。 除非重写此属性,否则继承自此类的所有类都使用与基类相同的类型转换器。 有关详细信息,请参阅 PowerShell SDK 和 Microsoft .NET Framework 文档。分析方法:如果源类型为字符串,并且目标类型具有名为
Parse
的方法,则调用该方法来执行转换。构造函数:如果目标类型有一个构造函数,该构造函数接受一个参数,且该参数的类型为源类型,则调用此构造函数来执行转换。
隐式转换运算符:如果源类型具有转换为目标类型的隐式强制转换运算符,则调用该运算符来执行转换。
显式强制转换运算符:如果源类型具有转换为目标类型的显式强制转换运算符,则调用该运算符来执行转换。 如果目标类型具有可以从源类型转换的显式强制转换运算符,则会调用该运算符来执行转换。
IConvertable:调用
System.Convert.ChangeType
来执行转换。
6.19 转换为 ordered
将任何值转换为按顺序排序的伪类型的规则如下所示:
- 如果值为哈希文本(§2.3.5.6),则结果是一个具有实现定义的类型的对象,其行为类似于哈希表,键的顺序与哈希文本中指定的顺序匹配。
- 否则,行为将由实现定义。
哈希文本(§2.3.5.6)只能转换为 ordered。 最后将得到 System.Collections.Specialized.OrderedDictionary
的实例。
6.20 转换为 pscustomobject
将任何值转换为伪类型 pscustomobject 的规则如下所示:
- 类型哈希表的值将转换为 PowerShell 对象。 哈希表中的每个键都会被转化为一个具有相应值的 NoteProperty。
- 否则,行为将由实现定义。
始终允许转换,但不更改值的类型。