浮点变量应为空或将空设置为0
我正在研究接受 [单个] $ durationMs
作为可选参数的函数。这应该是浮动值。因此,在我的函数中,我有以下代码来检查该代码是否已提供给该功能。如果提供了,我想将值添加到嵌套在另一个对象中的对象。
if ($DurationMS -ne $null) {
$MyObject.attributes | Add-Member -MemberType NoteProperty -Name 'duration.ms' -Value $DurationMS
}
除了测试它时,一切都很好,我在持续时间内得到0,我不知道为什么。
duration.ms
-----------
0
因此,我的病情正在评估为真,但我不明白为什么。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
[single]
是 value类型 ,这种类型的实例永远不可能$ null
。[单个] .ISVALUETYPE
返回$ true
告诉您它是一个值类型。$ null
仅适用于。net 参考类型 ,并告诉您参考 to no object 。因此,测试您的
:
[单]
typed$ durationms
参数变量$ null
[单]
实例的默认值是0
,以便您的$ durationms -ne $ null
有效地是0 -ne $ null
默认情况下,$ true
。在给定调用中检查参数是否传递给给定的(非使用)参数的可靠方法是咨询返回
1.2
和$ psboundParameters。 containskey('durationMs')
指示$ true
因此:
以下方面是偶然的:
if($ durationms)
仅在您还想考虑 explicit0
的参数向“没有值提供” ,因为使用[单个]
-Typed$ durationMs
,如果($ durationms)
与相同,如果($ durationms -ne 0)
0
映射到$ false
,任何非零值to$ true
。鉴于许多PowerShell操作员可以在 arrays (集合)中隐式运行,在这种情况下,它们充当 em> em> em>,返回匹配项的子阵列 - 通常最好将标量比较操作数放在LHS 上(在这种情况下,我们知道非文字操作数从定义上也是标量 - A
[单个]
实例 - 这没关系)。将标量放在LHS上避免误报 /负面因素,例如在以下示例中:< / p>
但是,即使在LHS
$ null
也可以表现出意外行为,即使用-lt
,<代码> -le ,-gt
和-GE
运算符,如此答案;例如:如果PowerShell为
$ NULL
提供了专门的测试,则可以避免这些陷阱;实施此类测试 - 形式$ var -is $ null
或$ var -isnull
- 是 github pr#10704 ;不幸的是,该公关被其创造者抛弃了,此后没有人拿起这项工作,这就是为什么不存在这样的测试的原因。。
。
AS Lee Dailey 指出,属性名称,例如
duration.ms
鉴于它包含。
,可能是有问题的,通常建议A nested 属性访问,鉴于(未引用的)。
作为< a href =“ https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about/about/about_operators#memember-member-access-operator- 。[single]
is a .NET value type, and instances of such types can never be$null
.[single].IsValueType
returning$true
tells you that it is a value type.$null
only applies to .NET reference types and tells you that is a reference to no object.It is therefore pointless to test your
[single]
-typed$DurationMS
parameter variable for being$null
:[single]
instance's default value is0
, so that your$DurationMS -ne $null
conditional is effectively0 -ne $null
by default, which is$true
.The robust way to check if an argument was passed to a given (non-mandatory) parameter in a given invocation is to consult the automatic
$PSBoundParameters
variable, as Santiago Squarzon suggests.-
); e.g., if your function is invoked with-DurationMS 1.2
,$PSBoundParameters['DurationMS']
returns1.2
, and$PSBoundParameters.ContainsKey('DurationMS')
indicates$true
Therefore:
The following aspects are incidental:
if ($DurationMs)
would only work if you also wanted to consider an explicit argument of0
to signal "no value was provided", because with a[single]
-typed$DurationMs
,if ($DurationMs)
is the same asif ($DurationMs -ne 0)
0
maps to$false
, and any nonzero value to$true
.Given that many PowerShell operators can implicitly operate on arrays (collections) as the LHS - in which case they act as filters, returning the subarray of matching items - it is generally better to place a scalar comparison operand on the LHS (in the case at we know that the non-literal operand is by definition also a scalar - a
[single]
instance - so that doesn't matter).Placing the scalar on the LHS avoids false positives / negatives, such as in the following example:
However, even on the LHS
$null
can exhibit unexpected behavior, namely with the-lt
,-le
,-gt
, and-ge
operators, as discussed in this answer; e.g.:If PowerShell offered a dedicated test for
$null
, these pitfalls could be avoided; implementing such a test - in the form$var -is $null
or$var -isnull
- was the subject of GitHub PR #10704; unfortunately, that PR was abandoned by its creator, and no one has picked up the work since, which is why no such test exists as of PowerShell 7.2.2.As Lee Dailey points out, a property name such as
duration.ms
can be problematic, given that it contains.
, which normally suggests a nested property access, given that an (unquoted).
serves as the member-access operator.