问题
I've started using PowerShell to get some things done and played with the variable $null in PowerShell.
I've encountered the problem that when I assign the variable $null to a variable defined in a class, the test returns false not true.
Example Code:
class test {
[string]$test1
}
$test = [test]::new()
$test.test1 = $null
$null -eq $test2 # tests true
$null -eq $test.test1 # tests false
Now the test of the undefinded variable $test2 returns true as every undefined variable in PowerShell is assigned $null.
But if I test the property test1 of the object test which I assigned $null tests false for $null
Is it because in PowerShell $null is an object with the value $null and now the property of the object is not $null as it has the object $null assigned to it with an empty value?
I've read into the docs of Microsoft "Everything you wanted to know about $null", but it does not enlighten me.
If I do not initialize the variable, then it will test true for $null.
回答1:
$test.test1 is not $null, it's empty string (because you explicitely defined it's value to be [string]):
C:\> $test.test1.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True String System.Object
Proof:
C:\> $test.test1 -eq ""
True
回答2:
If you're using a type contstraint like [string] or [int] Powershell initializes members at null-assignment with the default of the contrained type.
As @robdy states in above answer you've either check for the types default value or remove the constraint.
This may become more obvious if you're using a [int] type contstraint:
class test {
[int]$i1 = 42
}
$test = [test]::new()
Write-Host $test.i1
$test.i1 = $null
Write-Host $test.i1
Output:
42
0
回答3:
To elaborate on robdy's helpful answer:
By design,
[string]-typed variables, parameter variables, and custom-class properties in PowerShell do not store$null[1], only actual string values. Assigning$nullalways converts to''(the empty string).Below,
$varreceives'', not$null, due to being[string]-typed; therefore, the first-eqtest fails and the second succeeds.[string] $var = $null; $null -eq $var; '' -eq $varNote that other .NET reference types (as opposed to value types, which fundamentally cannot be null) are not affected in PowerShell; that is, you can assign
$nullto them. Notably, this also applies to[object]. Note that not type-constraining a variable / parameter / property is the same as[object]-typing it.
That an uninitialized
[string]property in a PowerShellclassnonetheless currently defaults to$nullshould be considered a bug - see GitHub issue #7294.The inconsistency becomes obvious if you explicitly initialize to
$null, which again converts to''and makes the test fail.class test { [string]$test1=$null }; $null -eq [test]::new().test1Should the bug be fixed and you truly need a
$nullvalue in a[string]-typed property - which is ill-advised in the context of PowerShell code - you'd have to use[NullString]::Value, as shown in the answer linked to below:class test { [string]$test1 = [NullString]::Value }; $null -eq [test]::new().test1
For more information, see this answer.
[1] The inability to store $null is a limitation that PowerShell imposes, in the interest of simplification. The underlying .NET type, System.String, typically does not have this limitation in other languages, notably not in C#.
来源:https://stackoverflow.com/questions/65322081/object-property-assigned-null-does-not-test-true-for-null