PowerShell类方法的引用参数?[参考资料][Uint64]

PowerShell类方法的引用参数?[参考资料][Uint64],powershell,Powershell,我有一个powershell类,需要传入对UInt64变量的引用,并从该方法返回一个值。我试图在下面的代码中执行类似的操作,但它给了我一个语法错误 也许我不需要添加?[ref]?因为默认情况下,所有变量都是powershell中的引用,包括uint64?但我只是不确定这是不是真的。。。。如果我遵循正常的C语言约定,那么该方法将获得参数的副本,而不是变量的实际引用。我似乎还记得C语言中关于装箱和拆箱int类型的一些东西。。。Powershell类方法的装箱Int是如何工作的 class Powe

我有一个powershell类,需要传入对UInt64变量的引用,并从该方法返回一个值。我试图在下面的代码中执行类似的操作,但它给了我一个语法错误

也许我不需要添加?[ref]?因为默认情况下,所有变量都是powershell中的引用,包括uint64?但我只是不确定这是不是真的。。。。如果我遵循正常的C语言约定,那么该方法将获得参数的副本,而不是变量的实际引用。我似乎还记得C语言中关于装箱和拆箱int类型的一些东西。。。Powershell类方法的装箱Int是如何工作的


class PowerHe11 {

    # Constructor
    PowerHe11() {
    }

    [void]AccessChannel(
        [UInt64]$ichan,
        [UInt64]$idata,
        [UInt64]$isize,
        [UInt64]$ireal,    
        [ref][UInt64]$otimeout,
        [ref][UInt64]$odata,
        [ref][UInt64]$ochan,
        [ref][UInt64]$osize

    ) {                  
        $osize = 64;  #Return this value to caller of method
    }
}
错误消息是:

At C:\Users\wmoore\Documents\fpga\zynq_pl\run_ps1\Untitled1.ps1:13 char:11
+         [ref][UInt64]$otimeout,
+              ~~~~~~~~
Multiple type constraints are not allowed on a method parameter.
At C:\Users\wmoore\Documents\fpga\zynq_pl\run_ps1\Untitled1.ps1:14 char:14
+         [ref][UInt64]$odata,
+              ~~~~~~~~
Multiple type constraints are not allowed on a method parameter.
At C:\Users\wmoore\Documents\fpga\zynq_pl\run_ps1\Untitled1.ps1:15 char:14
+         [ref][UInt64]$ochan,
+              ~~~~~~~~
Multiple type constraints are not allowed on a method parameter.
At C:\Users\wmoore\Documents\fpga\zynq_pl\run_ps1\Untitled1.ps1:16 char:14
+         [ref][UInt64]$osize
+              ~~~~~~~~
Multiple type constraints are not allowed on a method parameter.
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : MultipleTypeConstraintsOnMethodParam

给出了解决方案;让我添加一个解释和背景信息:

是官方的帮助主题

简而言之:

[ref]的主要目的是支持.NET方法中的ref和out参数;e、 例如,要调用该方法,请使用以下命令:

[int]$int=0;[int]::TryParse'42',[ref]$int

请注意,变量的类型必须与.NET方法所期望的类型匹配,并且在PowerShell中创建变量的唯一方法是也为其分配一个值,即使该值不相关,就像手头的out参数一样;[ref]转换的要求类似于在C中使用ref或out的需要

如果您对该方法分配的值不感兴趣,则可以传递[ref]$null

虽然您可以在PowerShell代码中使用它,但这样做很尴尬,如您的示例所示:

如您的答案所示,接收[ref]参数的PowerShell代码必须通过.value属性引用其值

不能对此类参数进行类型约束,因此将失去类型安全性

请注意,在函数和脚本中(与自定义类方法相反),语法上允许同时使用[ref]和目标数据类型(如[ref][UInt64]$otimeout),但在示例中没有意义,因为后者实际上被忽略;e、 g:

函数foo{param[ref][int]$p$p.Value+='!'}$bar=‘无’;foo[ref]$bar$酒吧

调用成功,$bar包含'none!',这意味着[int]类型约束被忽略

调用脚本和函数需要类似shell的、空格分隔的参数和允许的裸字字符串,这使得[ref]-cast调用需要。。。围绕参数,如上所示foo[ref]$bar

关于在自定义PuxBar类中使用,请注意,按设计,不等同于面向对象的语言(如C);也就是说,正在计划改进;不幸的是,从PowerShell 7.1开始,即使是有限的功能集也存在问题-请参阅

[ref]的技术背景:

[ref]与C中的ref不同,它不是一个语言关键字:它是一个类型,即它的is[ref]

因此,像[ref]$var这样的表达式是隐式构造[ref]实例的强制转换,绑定到[ref]类型的参数需要该实例

注意事项:

[ref]强制转换涉及到解析器魔法,因为您不能直接使用通常等价的[ref]::新的$var构造函数表达式作为强制转换[ref]$var的替代。 PowerShell需要magic知道$var引用的是变量对象本身,而不是变量的值,这在表达式中通常是这样的-后者确实与[ref]有关::新的$var-$var的值包装在[ref]实例中。 与[ref]$var等效的真正构造函数是[ref]::newGet变量var 断开:不要使用构造函数-[ref]::新建$int- 代替演员阵容-[ref]$int PS>[int]$int=0$null=[int]::TryParse'42',[ref]::new$int$int 0 !! $int没有更新,因为它的*value*被包装在[ref]实例中 通常,只有将[ref]强制转换与可变对象操作数一起使用才有意义

PowerShell允许您将任何值作为操作数传递,这在技术上是可行的,但没有意义,除非您将[ref]实例显式保存在变量中,将其作为参数传递,然后使用[ref]实例的.value属性访问更新后的值: 将[ref]实例保存在变量中,传递它,然后使用.Value获取 更新值。 PS>[ref]$intRef=0$null=[int]::TryParse'42',$intRef$intRef.值 42 给出了解决方案;让我添加一个解释和背景信息:

是官方的帮助主题

简而言之:

[ref]的主要目的是支持.NET方法中的ref和out参数;e、 例如,要调用该方法,请使用以下命令:

[int]$int=0;[int]::TryParse'42',[ref]$int

请注意,变量的类型必须与.NET方法所期望的类型匹配,并且在PowerShell中创建变量的唯一方法是也为其分配一个值,即使该值不相关,就像手头的out参数一样;[ref]转换的要求类似于在C中使用ref或out的需要

你可以通过[ref] $null,如果您对该方法分配的值不感兴趣

虽然您可以在PowerShell代码中使用它,但这样做很尴尬,如您的示例所示:

如您的答案所示,接收[ref]参数的PowerShell代码必须通过.value属性引用其值

不能对此类参数进行类型约束,因此将失去类型安全性

请注意,在函数和脚本中(与自定义类方法相反),语法上允许同时使用[ref]和目标数据类型(如[ref][UInt64]$otimeout),但在示例中没有意义,因为后者实际上被忽略;e、 g:

函数foo{param[ref][int]$p$p.Value+='!'}$bar=‘无’;foo[ref]$bar$酒吧

调用成功,$bar包含'none!',这意味着[int]类型约束被忽略

调用脚本和函数需要类似shell的、空格分隔的参数和允许的裸字字符串,这使得[ref]-cast调用需要。。。围绕参数,如上所示foo[ref]$bar

关于在自定义PuxBar类中使用,请注意,按设计,不等同于面向对象的语言(如C);也就是说,正在计划改进;不幸的是,从PowerShell 7.1开始,即使是有限的功能集也存在问题-请参阅

[ref]的技术背景:

[ref]与C中的ref不同,它不是一个语言关键字:它是一个类型,即它的is[ref]

因此,像[ref]$var这样的表达式是隐式构造[ref]实例的强制转换,绑定到[ref]类型的参数需要该实例

注意事项:

[ref]强制转换涉及到解析器魔法,因为您不能直接使用通常等价的[ref]::新的$var构造函数表达式作为强制转换[ref]$var的替代。 PowerShell需要magic知道$var引用的是变量对象本身,而不是变量的值,这在表达式中通常是这样的-后者确实与[ref]有关::新的$var-$var的值包装在[ref]实例中。 与[ref]$var等效的真正构造函数是[ref]::newGet变量var 断开:不要使用构造函数-[ref]::新建$int- 代替演员阵容-[ref]$int PS>[int]$int=0$null=[int]::TryParse'42',[ref]::new$int$int 0 !! $int没有更新,因为它的*value*被包装在[ref]实例中 通常,只有将[ref]强制转换与可变对象操作数一起使用才有意义

PowerShell允许您将任何值作为操作数传递,这在技术上是可行的,但没有意义,除非您将[ref]实例显式保存在变量中,将其作为参数传递,然后使用[ref]实例的.value属性访问更新后的值: 将[ref]实例保存在变量中,传递它,然后使用.Value获取 更新值。 PS>[ref]$intRef=0$null=[int]::TryParse'42',$intRef$intRef.值 42
class powerhe11 {

# Constructor
powerhe11() {
}

    [void]AccessChannel(
        [ref]$ichan

    ) {         
         $ichan.value = 0xbeef;
         
         Write-Host("ichan: {0}" -f $ichan.value)
    }

}



[UInt64]$dude = 0

$ser = [gvmuart]::new()

$ser.AccessChannel([ref]$dude);


Write-Host -BackgroundColor Green "DUDE: $dude"