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

2024-03-28

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

也许我不需要添加?[参考]?因为所有变量在 powershell 中默认都是引用,包括 uint64?但我只是不确定这是否属实......如果我遵循正常的 C 语言约定,那么该方法将获取参数的副本,而不是对变量的实际引用。我似乎记得 C# 中有关装箱和拆箱 int 类型的内容......C# int 类型的装箱和拆箱 https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/types/boxing-and-unboxingPowershell 类方法的装箱 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


你自己的答案 https://stackoverflow.com/a/65130083/45375显示解决方案;让我添加解释和背景信息:

about_Ref https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_Ref是官方帮助主题。

它的缺点是:

  • [ref]的主要目的是支持ref and out参数在.NET 方法;例如,调用System.Int32.TryParse https://learn.microsoft.com/en-US/dotnet/api/System.Int32.TryParse方法,使用以下内容:

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

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

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

  • 当你can在 PowerShell 代码中使用它,这样做是awkward,如您的示例所示:

    • 接收的 PowerShell 代码[ref]参数必须通过.Value财产,正如你的答案所示。

    • You 不能进行类型约束这样一个参数,所以你失去了类型安全。

      • 请注意,在函数和脚本- 与定制类相反methods- 这是语法上允许,但毫无意义两者都使用[ref]和目标数据类型(例如[ref][UInt64]$otimeout在你的例子中),因为后者实际上是ignored; e.g.:

        • function foo { param([ref] [int] $p) $p.Value += '!' }; $bar = 'none'; foo ([ref] $bar); $bar

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

    • 调用脚本和函数需要参数模式语法 https://stackoverflow.com/a/48779223/45375(类似 shell、空格分隔的参数、允许裸字字符串),使得[ref]-cast 调用通过 require 变得更加尴尬(...)围绕参数,如上所示(foo ([ref] $bar)).

    • 关于在自定义 PowerShell 中使用class是的,请注意PowerShell 的类支持 https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_Classes是 - 按设计 -not与面向对象的语言相当,例如C#;也就是说,已计划进行增强;不幸的是,从 PowerShell 7.1 开始,即使有限的功能集仍然存在问题 - 请参阅GitHub 问题 #6652 https://github.com/PowerShell/PowerShell/issues/6652.


技术背景[ref]:

[ref],不像ref在 C# 中,是not语言关键字: it is a type,即[System.Management.Automation.PSReference] https://learn.microsoft.com/en-US/dotnet/api/System.Management.Automation.PSReference (whose 类型加速器 https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_Type_Accelerators is [ref]).

因此,诸如此类的表达式[ref] $var is a cast那隐含地构造一个[ref]实例,需要绑定到[ref]- 类型参数。

Caveats:

  • There is parser magic involved in a [ref] cast, because you cannot directly use the normally equivalent [ref]::new($var) constructor expression as an alternative to cast [ref] $var.
    • PowerShell 需要魔法才能知道这一点$var指的是变量对象本身而不是变量的value,就像表达式中通常的情况一样 - 后者确实是发生的情况[ref]::new($var) - $var's value被包裹在一个[ref]实例。
    • 真正的构造函数相当于[ref] $var is [ref]::new((Get-Variable 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 允许您传递任何值作为操作数,这在技术上是可行的,但除非您显式保存,否则没有任何意义the [ref]实例在变量中,传递it作为参数,然后使用[ref]实例的.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
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PowerShell 类方法的引用参数? [参考][Uint64] 的相关文章

随机推荐

  • 如何将 argv[] 获取为 int?

    我有一段这样的代码 int main int argc char argv printf d t int argv 1 printf s t int argv 1 在外壳中我这样做 test 7 但第一个 printf 结果不是 7 我怎样
  • fscanf 无法正确读取浮点数

    这是一个家庭作业问题 我在使用 fscanf 从文本文件读取浮点值时遇到问题 基本上我试图从文件中读取浮点值并将它们存储在动态数组中 输入文件每行有两个浮点数 所以一行可能是 0 85 7 34 不带引号 所以我尝试使用 fscanf fp
  • 如何使用flask-ReSTplus记录帖子正文?

    如何记录预期发布的输入正文value字段出现以便用户知道要发布什么 目前使用以下数据 customer id service id customer name site name service type 我们可以使用上面的 json 来默
  • 将同步代码包装为异步任务的最佳方法是什么?

    我正在实现一个异步接口方法 返回任务 然而 我的实现必然是同步的 最好的方法是什么 有一些内置的方法可以做到这一点吗 以下是我正在考虑的几个选项 选项 1 Task FromResult return Task FromResult Com
  • 如何轮询目录以检查是否添加了新文件?

    我想轮询一个目录以检查是否有新文件添加到该目录中 如果添加了任何新文件 我想读取该文件 有人可以告诉我如何做到这一点吗 Java 7 有一个文件观察器API http java dzone com news how watch file s
  • 将 datetimeoffset 数据类型与 jTDS 结合使用

    jTDS 目前不支持datetimeoffsetSQL Server 2008 中引入的数据类型 任何人都可以建议是否有办法使用datetimeoffset使用 jTDS 键入 正如在 下层客户端的向后兼容性 部分中提到的日期时间偏移文档
  • Protobuf.net“一旦生成序列化器,就无法更改类型”

    我有一些使用 Protobuf net 的相当简单的代码 它抛出了一个非常奇怪的异常 在 MetaType cs 的第 167 行中 它抛出 InvalidOperationException 一旦生成序列化程序 就无法更改类型 这是什么意
  • 单击按钮时切换弹出模式

    我在页面上显示包含多个项目的弹出窗口时遇到问题 本质上 它是页面下方项目的垂直 列表 到目前为止我有两个 当我单击第一个项目时 第一组信息会正确显示 但是当我单击第二个项目时 它会在弹出窗口中显示第一组信息 任何帮助表示赞赏 谢谢 docu
  • AVFoundation 点击​​聚焦反馈矩形

    我正在开发一个 iPhone 应用程序 我直接使用 AVFoundation 通过相机捕获视频 我已经实现了一项功能来启用tap to focus为用户提供的功能 void focus CGPoint aPoint if HAS AVFF
  • 使用 webpack 和 React 模块解析失败,即使使用 babel-loader

    我正在尝试将 webpack 与 React 一起使用 但收到此错误 app main js 中出现错误 Module parse failed Users me app main js Line 2 Unexpected token Yo
  • gcc 警告:标量初始值设定项周围有大括号

    我有如下定义的查找表 并且正在使用 GCC 当我编译时 我收到警告 warning braces around scalar initializer 这个警告是什么意思 我应该如何初始化这个LUT 我在初始化这个结构时犯了错误吗 Help
  • 如何在 Google Colaboratory 的 Jupyter Notebook 中安装 svmutil?

    我想使用 svmutil 函数https github com Netflix vmaf tree master libsvm python https github com Netflix vmaf tree master libsvm
  • 为整个 iOS 应用程序快速使用自定义字体

    我知道要在屏幕上设置元素的自定义字体我可以简单地执行以下操作someLabel font UIFont name Exo 2 0 size 15 我想知道如何使用 swift 为整个应用程序设置它 一种黑客方法是对应用程序的每个元素执行我所
  • FLTK简单动画

    我可以成功编译并运行 Hello World 代码 现在我想做一些像动画这样的事情 我首先创建一个矩形类来实现 Fl widget 中的 draw class myRect public Fl Widget private Fl Color
  • 有没有一种简单的方法将 C++ 枚举转换为字符串?

    假设我们有一些命名枚举 enum MyEnum FOO BAR 0x50 我在谷歌上搜索的是一个脚本 任何语言 它扫描我的项目中的所有标头并生成每个枚举具有一个函数的标头 char enum to string MyEnum t 以及类似这
  • 如何使引导图标与标签中的文本内联显示?

    我有显示文本和箭头的引导导航药丸 不幸的是 如果文本太长 箭头就会出现在锚点的边框上 Html 看起来像这样 a href span Some longer sample text span i class pull right icon
  • Pandas 根据有时相反的两列删除重复项

    我有一个 DF 看起来像 c1 c2 c3 1 A B x 2 A C y 3 B A x 4 B D z 5 A B y 正如你所看到的 如果我们忽略这一点 第 1 行和第 3 行就会重复c1 and c2是不同的列 或者如果它们颠倒了
  • 如何避免 Go 中的初始化循环

    当我尝试编译这段代码时 package main import encoding json fmt net http func main fmt Println Hello playground const GET GET POST POS
  • 如何为表达式添加括号?

    我有一个想法 可以制作一个简单的程序 它将帮助我处理 C 等语言中的运算符优先级 其中最困难的部分是为表达式加上括号 例如 我想要这个 a x b x 转换成这样 a x b x 我在以下步骤中手动完成 a x b x a x b x a
  • PowerShell 类方法的引用参数? [参考][Uint64]

    我有一个 powershell 类 我需要传递对 UInt64 变量的引用并从方法返回一个值 我正在尝试执行类似于下面代码的操作 但它给了我一个语法错误 也许我不需要添加 参考 因为所有变量在 powershell 中默认都是引用 包括 u