Why does a [string] casted parameter with the 'value' $null in this example never throw an error (empty or $null), but a string with the value '$null' always throws? I would expect if passing a mandatory parameter, it is checked for $null/emptyness and thus an error is always thrown in these cases:
Function test_M_NoE ( [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [string] $x ) {}
# test cases. Uncomment one:
[string]$x = [string]$null
# $x = [string]$null
# [string]$x = $null
# $x = $null
"1:"; test_M_NoE [string]$x # never error
"2:"; test_M_NoE $x # always error
CodePudding user response:
The reason this works:
test_M_NoE [string]$x
Is that [string]$x
is not being interpreted the way you expect.
Let's change your test function definition to help us better see what's actually going on:
function test_M_NoE {
param(
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]$x
)
Write-Host "Argument value passed was: '$x'"
}
Now, let's try again:
PS ~> $x = $null
PS ~> test_M_NoE [string]$x
Argument value passed was: '[string]'
Aha! The argument expression [string]$x
did not result in an empty string - it resulted in the literal string value [string]
.
This is due to the fact that PowerShell attempts to parse command arguments differently from anything else. From the about_Parsing
help topic:
Argument mode is designed for parsing arguments and parameters for commands in a shell environment. All input is treated as an expandable string unless it uses one of the following syntaxes: [...]
So really, PowerShell interprets our argument expression like a double-quoted string:
test_M_NoE "[string]$x"
At which point the behavior makes sense - $x
is $null
, so it evaluates to an empty string, and the result of the expression "[string]$x"
is therefore just [string]
.
Enclose the argument expression in the $(...)
subexpression operator to have it evaluated as a value expression instead of as an expandable string:
test_M_NoE $([string]$x)