3

在调查一些问题的过程中,我发现原因是意外不同的转换为看似相同的输入数据的 string[]。即,在下面的代码中,两个命令都返回相同的两个项 File1.txt 和 File2.txt。但是转换为 string[] 会产生不同的结果,请参阅注释。

任何想法为什么会这样?这可能是一个错误。如果有人也这么认为,我会提交。但是很高兴了解正在发生的事情并避免这样的陷阱。

# *** WARNING
# *** Make sure you do not have anything in C:\TEMP\Test
# *** The code creates C:\TEMP\Test with File1.txt, File2.txt

# Make C:\TEMP\Test and two test files
$null = mkdir C:\TEMP\Test -Force
1 | Set-Content C:\TEMP\Test\File1.txt
1 | Set-Content C:\TEMP\Test\File2.txt

# This gets just file names
[string[]](Get-ChildItem C:\TEMP\Test)

# This gets full file paths
[string[]](Get-ChildItem C:\TEMP\Test -Include *)

# Output:
# File1.txt
# File2.txt
# C:\TEMP\Test\File1.txt
# C:\TEMP\Test\File2.txt
4

1 回答 1

9

好吧,我得到了一些线索(可能发布这个问题激发了我的想法)。是的,这是一种陷阱,不仅在 PowerShell 中(但 PowerShell 使之成为可能)。

显然 PowerShell 仅ToString()用于转换。这是一个错误的假设,System.IO.FileInfo.ToString()返回FullName. 反射器显示它返回的base.OriginalPath正是构造函数中传递的内容,而不是完整路径。

这是演示:

Set-Location C:\TEMP\Test
[string](New-Object IO.FileInfo File1.txt)
[string](New-Object IO.FileInfo C:\TEMP\Test\File1.txt)
[string](New-Object IO.FileInfo ./..//Test///..Test\File1.txt)

# Output:
# File1.txt
# C:\TEMP\Test\File1.txt
# ./..//Test///..Test\File1.txt

因此,看起来第一个Get-ChildItem在创建FileInfo对象时仅使用名称,而第二个Get-ChildItem带有–Include参数的则使用完整路径。这是一个错误吗?现在看来值得商榷。这可能是一个功能,值得怀疑,但仍然有一些潜在的原因。不过我怀疑……</p>

于 2010-04-30T13:01:39.770 回答