我有一个powershell类,我需要将它作为对UInt64变量的引用传递给它,并从该方法返回一个值。我正在尝试做一些类似下面的代码,但它给我一个语法错误。
也许我不需要加什么?裁判?因为所有变量在powershell中都是默认的引用,包括uint64?但我只是不确定这是不是真的...如果我遵循普通的C语言约定,那么该方法将获得参数的副本,而不是对变量的实际引用。我似乎在C#中回想起一些关于装箱和拆箱int类型的事情……boxing and unboxing c# int type如何使用boxing Int for Powershell类方法?
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发布于 2020-12-05 01:23:11
Your own answer展示了解决方案;让我添加一个解释和背景信息:
about_Ref是官方的帮助主题。
简而言之:
[ref]**'s的主要用途是支持** ref out methods中的和 .NET 参数;例如,要调用System.Int32.TryParse方法,请使用以下命令:- `[int] $int = 0; [int]::TryParse('42', [ref] $int)`- Note that the **variable's type must match the type expected by the .NET method**, and that the only way to create a variable in PowerShell is to also assign it a value (even if that value is irrelevant, as is the case with the `out` parameter at hand); the `[ref]` cast is required (analogous to the need to use `ref` or `out` in C#.- You may pass `[ref] $null` if you're not interested in the value being assigned by the method.- **PowerShell code that receives a** **`[ref]`** **argument must refer to its value via the** **`.Value`** **property**, as your answer shows.- **You** _**cannot type-constrain**_ **such a parameter**, so you lose type safety. - Note that in _function and scripts_ - as opposed to custom-class _methods_ - it is _syntactically allowed, but pointless_ to use both `[ref]` and a target data type (such as `[ref][UInt64]$otimeout` in your example), because the latter is effectively _ignored_; e.g.: - `function foo { param([ref] [int] $p) $p.Value += '!' }; $bar = 'none'; foo ([ref] $bar); $bar` - The call succeeds and `$bar` contains `'none!'`, which implies that the `[int]` type constraint was ignored.- Calling scripts and functions requires [argument-mode syntax](https://stackoverflow.com/a/48779223/45375) (shell-like, whitespace-separated arguments, bareword strings allowed), making the `[ref]`-cast invocation more awkward by requiring `(...)` around the argument, as shown above (`foo ([ref] $bar)`).- With respect to use in custom PowerShell `class`es, note that [**PowerShell's class support**](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_Classes) **is - by design -** _**not**_ **on par with that of OO-focused languages such as** **`C#`**; that said, enhancements are planned; unfortunately, even the limited feature set still has problem as of PowerShell 7.1 - see [GitHub issue #6652](https://github.com/PowerShell/PowerShell/issues/6652).有关 [ref]的技术背景
与C#中的ref不同,is a language keyword:it is a ,即[System.Management.Automation.PSReference] (其是[ref])。
因此,像[ref] $var这样的表达式是隐式构造[ref]实例的强制转换,绑定到[ref]-typed参数需要该实例。
警告
因为您不能直接使用通常等价的[ref]构造函数表达式作为强制转换[ref] $var的替代方法,所以
[ref]::new($var)解析器的魔力。$var引用的是一个变量对象本身,而不是像表达式中通常那样引用变量的值--后者确实是[ref]::new($var)的结果--$var的值被包装在一个[ref] [ref] $var的真正构造函数中,这个构造函数与[ref] $var是等价的# BROKEN: Do not use a constructor - [ref]::new($int) -
# in lieu of a cast - [ref] $int
PS> [int] $int = 0; $null = [int]::TryParse('42', [ref]::new($int)); $int
0 # !! $int was NOT updated, because its *value* was wrapped in a [ref] instance[ref] operand.的变量(对象)的转换时才有意义
- PowerShell lets you pass any value as the operand, which technically works, but makes no sense unless you explicitly save _the_ _`[ref]`_ _instance_ in a variable, pass _it_ as the argument, and then use the `[ref]` instance's `.Value` property to access the updated value:# Save a [ref] instance in a variable, pass it, then use .Value to get the
# updated value.
PS> [ref] $intRef = 0; $null = [int]::TryParse('42', $intRef); $intRef.Value
42发布于 2020-12-04 00:32:13
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"https://stackoverflow.com/questions/65129689
复制相似问题