不一致的绑定在将DirectoryInfo对象进行管道传递时。

huangapple go评论64阅读模式
英文:

Inconsistent binding when piping DirectoryInfo objects

问题

I've often used a construct similar to this (using aliases for brevity):

gci -ad | %{$_ | gci}

which works fine. But when trying to help another user on this forum, I found that the following doesn't work:

gci -ad | %{$_.Parent | gci}

throws the following error for each iteration:

gci : Cannot find path 'C:\Users\keith\Documents\Documents' because it does not exist.
At line:1 char:25
+ gci -ad | %{$_.Parent | gci}
+                         ~~~
    + CategoryInfo          : ObjectNotFound: (C:\Users\keith\Documents\Documents:String) [Get-ChildItem], ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand

even though:

gci -ad | %{$_.GetType() -eq $_.Parent.GetType()}

produces a screen full of True.

I'm pretty sure it has something to do with parameter binding, but would like to understand the apparent inconsistency.

英文:

I've often used a construct similar to this (using aliases for brevity):

gci -ad | %{$_ | gci}

which works fine. But when trying to help another user on this forum, I found that the following doesn't work:

gci -ad | %{$_.Parent | gci}

throws the following error for each iteration:

gci : Cannot find path 'C:\Users\keith\Documents\Documents' because it does not exist.
At line:1 char:25
+ gci -ad | %{$_.Parent | gci}
+                         ~~~
    + CategoryInfo          : ObjectNotFound: (C:\Users\keith\Documents\Documents:Stri
   ng) [Get-ChildItem], ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemC
   ommand

even though:

gci -ad | %{$_.GetType() -eq $_.Parent.GetType()}

produces a scrennfull of True.

I'm pretty sure it has something to do with parameter binding, but would like to understand the apparent inconsistancy....

答案1

得分: 2

以下是您要翻译的内容:

"最容易了解发生了什么的方法是使用测试函数模拟绑定,但问题是,正如您可能知道的,在.NET Framework中,当将DirectoryInfo实例强制转换为字符串时,结果将是其.Name属性值,而不是.NET中的情况,其中强制转换会导致.FullName属性。

由于调用.Parent属性返回的对象没有ETS属性.PSPath,因此输入对象将绑定到Path参数并强制转换为字符串。

假设您同时拥有PowerShell的两个版本,您可以尝试以下内容以查看差异:

function Test-Binding {
    [CmdletBinding(DefaultParameterSetName='Items')]
    param(
        [Parameter(ParameterSetName='Items', Position=0, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
        [string[]]
        ${Path},

        [Parameter(ParameterSetName='LiteralItems', Mandatory=$true, ValueFromPipelineByPropertyName=$true)]
        [Alias('PSPath')]
        [string[]]
        ${LiteralPath}
    )

    process {
        $PSBoundParameters
        $PSBoundParameters.Clear()
    }
}

(Get-Item .), (Get-Item .).Parent | Test-Binding
英文:

Easiest way to see what's happening is to emulate the binding with a test function, but the issue is, as you might know in .NET Framework when a DirectoryInfo instance is coerced into a string the result will be it's .Name property value as opposed to .NET where the coercion results in the .FullName property.

Since the object returned by calling the .Parent property does not have the ETS Property .PSPath, the input object will be bound the the Path Parameter and coerced to a string.

Assuming you have both versions of PowerShell, you can try the following to see the difference:

function Test-Binding {
    [CmdletBinding(DefaultParameterSetName='Items')]
    param(
        [Parameter(ParameterSetName='Items', Position=0, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
        [string[]]
        ${Path},

        [Parameter(ParameterSetName='LiteralItems', Mandatory=$true, ValueFromPipelineByPropertyName=$true)]
        [Alias('PSPath')]
        [string[]]
        ${LiteralPath}
    )

    process {
        $PSBoundParameters
        $PSBoundParameters.Clear()
    }
}

(Get-Item .), (Get-Item .).Parent | Test-Binding

huangapple
  • 本文由 发表于 2023年2月18日 04:15:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/75488885.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定