Don Cruickshank's helpful answer provides one piece of the puzzle, but let me try give a comprehensive overview:
By itself, a [<fullTypeNameOrTypeAccelerator>]
expression is a type literal, i.e. a reference to a .NET type in the form of a System.Reflection.TypeInfo
instance, which is rich source of reflection on the type it represents.
<fullTypeNameOrTypeAccelerator>
can be the full name of a .NET type (e.g., [System.Text.RegularExpressions.Regex]
- optionally with the System.
prefix omitted ([Text.RegularExpressions.Regex]
) or the name of a PowerShell type accelerator (e.g, [regex]
)
Type literals are also used in the following constructs:
As casts, to coerce the (RHS[1]) operand to the specified type, if possible:
[datetime] '1970-01-01' # convert a string to System.DateTime
- Note that PowerShell casts are much more flexible than in C#, for instance, and type conversions frequently happen implicitly - see this answer for more information. The same rules apply to all the other uses listed below.
As type constraints:
To specify the type of a parameter variable in a function or script:
function foo { param([datetime] $d) $d.Year }; foo '1970-01-01'
To lock in the type of a regular variable for all future assignments:[2]
[datetime] $foo = '1970-01-01'
# ...
$foo = '2021-01-01' # the string is now implicitly forced to [datetime]
As the RHS of the -is
and -as
operators, for type tests and conditional conversions:
-is
tests not only for the exact type, but also for derived types as well as interface implementations:
# Exact type match (the `Get-Date` cmdlet outputs instances of [datetime])
(Get-Date) -is [datetime] # $true
# Match via a *derived* type:
# `Get-Item /` outputs an instance of type [System.IO.DirectoryInfo],
# which derives from [System.IO.FileSystemInfo]
(Get-Item /) -is [System.IO.FileSystemInfo] # $true
# Match via an *interface* implementation:
# Arrays implement the [System.Collections.IEnumerable] interface.
1..3 -is [System.Collections.IEnumerable] # true
-as
converts the LHS instance to an instance of the RHS type if possible, and returns $null
otherwise:
'42' -as [int] # 42
'foo' -as [int] # $null
[1] In the context of operators and mathematical equations, the initialisms LHS and RHS are commonly used, referring to the left-hand side and right-hand side operands, respectively.
[2] Technically, there is no real difference between a parameter and a regular variable: the type constraints functions the same way in both cases, but parameter variables, after having been bound (assigned to) automatically on invocation, aren't usually assigned to again.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…