英文:
PowerShell -as [Type] syntax
问题 {#heading}
我在Get-FileHash函数中发现了以下语句(来源:Microsoft.PowerShell.Utility.psm1):
$hasherType = "System.Security.Cryptography.${Algorithm}CryptoServiceProvider" -as [Type]
我的问题是:
- 写"-as [Type]"和简单写"[Type]$xxxx"之间有什么区别(如果有的话)?
- ${Algorithm}也可以定义为:$($Algorithm) 吗?
英文:
I found in the Get-FileHash function (source: Microsoft.PowerShell.Utility.psm1) this statement:
$hasherType = "System.Security.Cryptography.${Algorithm}CryptoServiceProvider" -as [Type]
my questions are:
- what is the difference (if any) writing "-as [Type]" or just simply "[Type]$xxxx?
- ${Algorithm} could be defined as well: $($Algorithm)?
答案1 {#1}
得分: 3
- 使用
-as [Type]
或者只是简单地使用[Type]$xxxx
有什么区别(如果有的话)?
-as
操作符受到了C#中的所谓无检查转换操作符的启发(对应于C#关键字as
) - 在转换失败的情况下,该操作将简单地评估为$null
。这种行为与常规的[type]$value
转换不同,后者在失败时会引发异常。
测试$null
通常比捕获和处理异常更快,因此在预期某些值不符合给定类型的情况下,这可能会有用:
$bunchOfMixedValues | ForEach-Object {
$thing = $_ -as [TargetType]
if ($null -ne $thing) {
# 处理 $thing
}
else {
# 无需关心无效输入,什么都不做
}
}
${Algorithm}
也可以这样定义:$($Algorithm)
吗?
最终结果是相同的,是的。
${...}
表示与$...
完全相同的元素 - 变量路径文字表达式。您可以将{
和}
括号视为变量表达式的_引号_,换句话说,它们_限定了_变量名称的边界 - 因此PowerShell知道不要尝试展开$AlgorithmCryptoServiceProvider
。因此,在生成代码时使用${...}
语法更安全,这就是为什么在许多由Microsoft编写的模块中看到它的原因。
英文:
> what is the difference (if any) writing -as [Type]
or just simply [Type]$xxxx
?
The -as
operator is heavily inspired by the so-called unchecked conversion operator from C# (corresponding to the C# keyword as
) - the operation will simply evaluate to $null
in case of conversion failure. This behavior differs significantly from a regular [type]$value
cast, which will throw an exception on failure.
Testing for $null
is usually faster than capturing and handling an exception, so this can be useful in situations where you expect some values not to conform to a given type:
$bunchOfMixedValues |ForEach-Object {
$thing = $_ -as [TargetType]
if ($null -ne $thing) {
# process $thing
}
else {
# no need to care about invalid input, do nothing
}
}
> ${Algorithm}
could be defined as well: $($Algorithm)
?
The end result would be the same, yes.
${...}
represents the exact same element as $...
- a variable path literal expression. You can think of the {
and }
brackets as quotation marks for variable expressions, in other words they qualify the boundary of the variable name - so PowerShell knows not to attempt to expand $AlgorithmCryptoServiceProvider
instead.
It's therefore safer to use the ${...}
syntax when generating code for example, which is why you'll see it in lots of Microsoft-authored modules.