代码之家  ›  专栏  ›  技术社区  ›  Malcolm McCaffery

在PowerShell中通过引用传递类属性

  •  0
  • Malcolm McCaffery  · 技术社区  · 4 年前

    在Windows 11上使用PowerShell ISE

    PS C:\Users\malcolm> $PSVersionTable
    
    Name                           Value                                                              
    ----                           -----                                                              
    PSVersion                      5.1.22000.282                                                      
    PSEdition                      Desktop                                                            
    PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}                                            
    BuildVersion                   10.0.22000.282                                                     
    CLRVersion                     4.0.30319.42000                                                    
    WSManStackVersion              3.0                                                                
    PSRemotingProtocolVersion      2.3                                                                
    SerializationVersion           1.1.0.1  
    

    我需要在PowerShell中传递一个类属性作为引用。

    Function Add-Five
    {
        param([ref]$value)
        $value.Value+=5
    }
    
    $a = 5
    Add-Five -value ([ref]$a)
    Write-Host "A = $a"
    

    正如预期的那样,该输出 10

    class MyClass
    {
        $a
    }
    Function Add-Five
    {
        param([ref]$value)
        $value.Value+=5
    }
        
    $class = New-Object MyClass
    $class.a = 5
    Add-Five -value ([ref]$class.a)
    Write-Host "A = $($class.a)"
    

    输出为 5.

    Function Add-FiveSpecial
    {
        param($className,$propertyName)
        (Get-Variable -Name $className).Value.$propertyName += 5    
    }
    
    Add-FiveSpecial -className "class" -propertyName "a"
    Write-Host "A = $($class.a)"
    

    哪些输出

    0 回复  |  直到 4 年前
        1
  •  2
  •   mklement0    4 年前

    这个 [ref] 关键字 )是到 .NET API ref out 参数 .

    很少在纯PowerShell代码中使用,最好避免在那里使用

    简而言之:

    • [参考] 仅在PowerShell中有效 ,它真正为给定变量创建别名 对象

    • 而PowerShell允许你施放 任何 [参考] ,用任何东西 另外 而不是它作用的变量 ,因此无效。 [1]

    This answer 有更多关于 [参考]

    正确使用 [参考] :带有 变量 :

    PS> $foo = 42; $bar = [ref] $foo; ++$bar.Value; $foo
    43  # OK, incrementing the .Value of $bar updated the value of $foo
    

    语法注释 直接地 [参考] . 因此,尝试将其用作变量类型约束会 工作: [ref] $bar = $foo

    # Declare a variable to use with [ref]
    # Note: No need to type the variable.
    $intVal = $null
    
    # Pass the variable via [ref] to receive the out parameter value
    # of [int]::TryParse()
    $null = [int]::TryParse('42', [ref] $intVal)
    
    # $intVal now contains 42
    

    毫无意义地使用 [参考] 任何其他 表示 : [1]

    PS> $foo = [pscustomobject] @{ prop = 42 }; $bar = [ref] $foo.prop; ++$bar.Value; $foo.prop
    42  # !! $foo's value was NOT updated.
    

    您的选择 是:

    • 如果 Add-Five 无法修改,请使用 辅助变量

        class MyClass{ $a = 0 }
      
        Function Add-Five {
          param([ref]$value)
          $value.Value+=5
        }
      
        $myObj = [MyClass]::new()
      
        # Create and use an aux. variable.
        $aux = $myObj.a
        Add-Five ([ref] $aux)
      
        # Update the property via the updated aux. variable.
        $myObj.a = $aux
        # myObj.a now contains 5
      
      • 允许 输出 (返回)新值并将其分配给属性:

        class MyClass{ $a = 0 }
        
        Function Add-Five {
          param($value) # regular parameter (variable)
          $value + 5    # output the new value
        }
        
        $myObj = [MyClass]::new()
        
        # Pass the property value and assign back to it.
        $myObj.a = Add-Five $myObj.a 
        # myObj.a now contains 5
        
      • Mathias R. Jessen 建议,传递一个 [MyClass] 例子 作为一个整体 让它更新那里的属性:

        class MyClass{ $a = 0 }
        
        Function Add-Five {
          param([MyClass] $MyObj) # expect a [MyClass] instance as a whole
          $MyObj.a += 5           # update the property directly
        }
        
        $myObj = [MyClass]::new()
        
        Add-Five $myObj
        # myObj.a now contains 5
        

    [参考] 如概念图所示 about_Ref ; 相反,它使用 可供替代的 以允许对其进行更新 从子范围 Get-Variable / Set-Variable cmdlet)。

    推荐文章