gpt4 book ai didi

c# - 函数中的参数类型验证 - 二进制模块与脚本模块

转载 作者:太空狗 更新时间:2023-10-29 20:32:53 32 4
gpt4 key购买 nike

在构建了许多 PowerShell 模块(二进制和脚本)之后,这两个模型之间仍然存在我无法完全理解的不一致之处。也许你们中的一个人可以阐明这个问题。

  1. 想象一个接受单个 DateTime 值的函数。在脚本函数中,我会将其定义为 [DateTime] 参数;在 C# 函数中,参数的类型为 DateTime。到目前为止,一切顺利。

  2. 现在想象将一个 DateTime 传递给该函数,并使用 Add-Member 添加了一个额外的注释属性。尽管被定义为 [DateTime],脚本函数参数还是很乐意接受这个值,因为它实际上是一个 PSObject 包装了原始的 DateTime(并且可能包含其他成员)在使用时展开 - 我希望我在这里使用的是正确的术语。正如预期的那样,传递除(包装的)DateTime 之外的其他内容会失败,从而使该函数或多或少是类型安全的。

  3. 等效的 C# 函数将参数定义为 DateTime,因此据我所知,它无法访问附加参数。毕竟,参数提供的唯一“接口(interface)”来自 DateTime 类型。

  4. 或者,我可以将 C# 函数的参数类型定义为 PSObject,但是我必须自己对 PSObject 的类型进行检查基础对象

我的逻辑有问题吗?或者,更重要的是,是否有解决此问题的方法,以便我仍然可以将二进制模块的类型检查留给 PowerShell?

非常感谢!

最佳答案

你既对又错 - 这完全取决于目标参数是否为值类型(例如 System.DateTime 是一个结构) - 在这种情况下,一切都在类型上丢失参数绑定(bind)期间的强制。

但是,如果参数类型是引用类型,您可以使用 PSObject.AsPSObject()“恢复”PSObject 包装器| .

为了便于复制,我在纯(-ish)PowerShell 中提出了以下示例,但我相信它充分说明了我的观点

将以下内容粘贴到 C# 源文件中(例如,TestCmdlets.cs):

using System;
using System.Management.Automation;

namespace TestPSObject
{
// This will be our parameter type
public class TestObject {}

// This will be our reference type test cmdlet
[Cmdlet(VerbsDiagnostic.Test, "PSObjectByRef")]
public class TestPSObjectByRefCommand : Cmdlet
{
[Parameter(Mandatory=true)]
public TestObject TestObject
{
get { return testObject; }
set { testObject = value; }
}
private TestObject testObject;

protected override void ProcessRecord()
{
// If this works, we should receive an object with
// identical psextended properties
WriteObject(PSObject.AsPSObject(this.TestObject));
}
}

// This will be our value type test cmdlet
[Cmdlet(VerbsDiagnostic.Test, "PSObjectByValue")]
public class TestPSObjectByValueCommand : Cmdlet
{
[Parameter(Mandatory=true)]
public DateTime DateTime
{
get { return dateTime; }
set { dateTime = value; }
}
private DateTime dateTime;

protected override void ProcessRecord()
{
// If this works, we should receive an object with
// identical psextended properties (hint: we won't)
WriteObject(PSObject.AsPSObject(this.DateTime));
}
}
}

现在,在您的 shell 中,编译并导入我们的测试模块:

Add-Type -Path .\TestCmdlets.cs -OutputAssembly TestPSObject.dll -OutputType Library
Import-Module .\TestPSObject.dll

接下来我们创建我们的测试对象并为它们添加一个注释属性:

$TestObject = New-Object TestPSObject.TestObject
$TestObject |Add-Member -MemberType NoteProperty -Name TestProperty -Value "Hi there!"
$DateTime = Get-Date
$DateTime |Add-Member -MemberType NoteProperty -Name TestProperty -Value "Hi there!"

当您取消引用 TestProperty 成员时,它们现在都返回字符串值 Hi there!

现在进行实际测试:

$TestObjectAfter = Test-PSObjectByRef -TestObject $TestObject
$DateTimeAfter = Test-PSObjectByValue -DateTime $DateTime

这仍然会返回你好!:

$TestObjectAfter.TestProperty

但这不会:

$DateTimeAfter.TestProperty

关于c# - 函数中的参数类型验证 - 二进制模块与脚本模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48403276/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com