You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在C#中使用ValueFromPipelineByPropertyName时获取原始管道对象的方法

如何在C# Cmdlet中获取管道传入的原始对象(使用ValueFromPipelineByPropertyName时)

刚好碰到过类似的场景,给你说个简单靠谱的解决办法——当你用ValueFromPipelineByPropertyName=true绑定单个属性时,想要拿到整个原始管道对象,其实不用找什么复杂的API,只要给你的Cmdlet加个专门接收原始对象的参数就行。

具体实现步骤

首先修改你的Cmdlet代码,新增一个InputObject参数,专门用来接收整个管道对象:

[Cmdlet(VerbsLifecycle.Start, "Foo")]
public class StartFooCommand : PSCmdlet
{
    // 这个参数负责接收完整的原始管道对象
    [Parameter(ValueFromPipeline = true)]
    public PSObject InputObject { get; set; }

    [Parameter(Position = 0, Mandatory = true, ValueFromPipelineByPropertyName = true)]
    public string Name { get; set; }

    protected override void ProcessRecord()
    {
        // 这里的InputObject就是你要的原始管道对象
        if (InputObject != null)
        {
            WriteObject(InputObject);
        }
        
        // 这里正常执行你的Foo相关操作,比如用Name参数做事情
        // 示例:WriteVerbose($"Starting Foo for {Name}");
    }
}

为什么这样可行?

PowerShell的管道绑定逻辑很聪明:当它看到有参数设置了ValueFromPipeline=true(也就是我们的InputObject),同时另一个参数设置了ValueFromPipelineByPropertyName=true(Name),它会先把整个管道对象绑定到InputObject,然后再自动从这个对象里提取Name属性的值绑定到Name参数。这样你既能用到Name属性的值,又能拿到完整的原始对象传递给下一个Cmdlet。

另一种备选方法(不推荐,但可以应急)

如果你不想新增参数,也可以通过GetVariableValue方法获取PowerShell内置的$input变量,但这种方式可读性差,也不符合Cmdlet的设计规范,只适合临时调试用:

protected override void ProcessRecord()
{
    var inputEnumerator = (IEnumerator)GetVariableValue("input");
    if (inputEnumerator.MoveNext())
    {
        var pipelineObject = inputEnumerator.Current;
        WriteObject(pipelineObject);
    }
    
    // 执行Foo操作...
}

验证效果

现在你运行脚本:

$foo = New-Object PSObject -prop @{ Name = "Frank"; Bar = "Baz" }
$foo | Start-Foo | Use-Foo

Start-Foo会把原始的$foo对象完整输出到管道,Use-Foo就能接收到包含Bar属性的完整对象了。

内容的提问来源于stack exchange,提问作者Chad Schouggins

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:38:05