浮点变量应为空或将空设置为0

发布于 2025-01-21 17:53:50 字数 408 浏览 0 评论 0 原文

我正在研究接受 [单个] $ durationMs 作为可选参数的函数。这应该是浮动值。因此,在我的函数中,我有以下代码来检查该代码是否已提供给该功能。如果提供了,我想将值添加到嵌套在另一个对象中的对象。

if ($DurationMS -ne $null) {
$MyObject.attributes | Add-Member -MemberType NoteProperty -Name 'duration.ms' -Value $DurationMS
}

除了测试它时,一切都很好,我在持续时间内得到0,我不知道为什么。

duration.ms
-----------
          0

因此,我的病情正在评估为真,但我不明白为什么。

I'm working on a function that accepts [Single]$DurationMS as an optional parameter. This is supposed to be float value. So in my function I have the following code to check if its been provided to the function. if it is provided I want to add the value to an object nested in another object.

if ($DurationMS -ne $null) {
$MyObject.attributes | Add-Member -MemberType NoteProperty -Name 'duration.ms' -Value $DurationMS
}

All looks fine except when I test it I get 0 in the duration and I can't figure out why.

duration.ms
-----------
          0

so my condition is evaluating to true but I don't understand why.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

跨年 2025-01-28 17:53:50

因此:

# Was an argument passed to -DurationMS?
if ($PSBoundParameters.ContainsKey('DurationMS')) {
  $MyObject.attributes | 
    Add-Member -MemberType NoteProperty -Name 'duration.ms' -Value $DurationMS
}

以下方面是偶然的:

  • if($ durationms)仅在您还想考虑 explicit 0 的参数向“没有值提供” ,因为使用 [单个] -Typed $ durationMs 如果($ durationms)相同,如果($ durationms -ne 0)

    • PowerShell允许您在布尔上下文中使用任何键入的表达式;使用数字类型, 0 映射到 $ false ,任何非零值to $ true
    • 虽然这种隐式的对树 - 流行的转换行为通常很方便,但它具有陷阱 - 请参阅有关规则的摘要。


  • 鉴于许多PowerShell操作员可以在 arrays (集合)中隐式运行,在这种情况下,它们充当 em> em> em>,返回匹配项的子阵列 - 通常最好将标量比较操作数放在LHS 上(在这种情况下,我们知道非文字操作数从定义上也是标量 - A [单个] 实例 - 这没关系)。

    • 将标量放在LHS上避免误报 /负面因素,例如在以下示例中:< / p>

        $ arr = 0,$ null
      #!! !! - &gt; 'null',因为(0,$ null)-ne $ null过滤
      #!! !!数组到 @(0)和[bool] @() - 也许令人惊讶 - 是$ false
      if($ arr -ne $ null){'not null'} else {'null'}
      
      #好的,LHS上的$ null
      # - &gt; “不是零”
      if($ null -ne $ arr){'not null'} else {'null'} 
       
    • 但是,即使在LHS $ null 也可以表现出意外行为,即使用

      -lt ,<代码> -le , -gt -GE 运算符,如此答案;例如:

        $ null -lt 0#! - &gt; $ true-即使[int] $ null产生0
       
    • 如果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:

    • A [single] instance's default value is 0, so that your $DurationMS -ne $null conditional is effectively 0 -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.

    • This variable contains a dictionary that has entries for all explicitly passed arguments, keyed by their parameter names (sans prefix -); e.g., if your function is invoked with -DurationMS 1.2, $PSBoundParameters['DurationMS'] returns 1.2, and $PSBoundParameters.ContainsKey('DurationMS') indicates $true

Therefore:

# Was an argument passed to -DurationMS?
if ($PSBoundParameters.ContainsKey('DurationMS')) {
  $MyObject.attributes | 
    Add-Member -MemberType NoteProperty -Name 'duration.ms' -Value $DurationMS
}

The following aspects are incidental:

  • if ($DurationMs) would only work if you also wanted to consider an explicit argument of 0 to signal "no value was provided", because with a [single]-typed $DurationMs, if ($DurationMs) is the same as if ($DurationMs -ne 0)

    • PowerShell allows you to use an expression of any type in a Boolean context; with numeric types, 0 maps to $false, and any nonzero value to $true.
    • While this implicit to-Boolean conversion behavior is generally convenient, it has its pitfalls - see the bottom section of this answer for a summary of the rules.
  • 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:

      $arr = 0, $null
      # !! -> 'null', because (0, $null) -ne $null filters the
      # !!    array to @(0), and [bool] @() - perhaps surprisingly - is $false
      if ($arr -ne $null) { 'not null' } else { 'null' }
      
      # OK, with $null on the LHS
      # -> 'not null'
      if ($null -ne $arr) { 'not null' } else { 'null' } 
      
    • 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.:

       $null -lt 0 # !! -> $true - even though [int] $null yields 0
      
    • 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文