PowerShell 5 和 类 - 无法将类型 "X" 的 "X" 值转换为类型 "X"

PowerShell 5 and classes - Cannot convert the "X" value of type "X" to type "X"

我正在尝试使用 PowerShell 的 classes,这是将相关数据分组在一起的非常方便的方法,但处理行为却非常乏味。简化场景:一个 PS 定义 class 的脚本和另一个使用 class.

的脚本

Common.ps1

class X
{
    [string] $A
} 

Script1.ps1

. $PSScriptRoot\Common.ps1

[X] $v = New-Object X

一切都很好 - 您可以 运行 Script1.ps1 任意次数而不会出现任何问题 - 直到您在 Common.ps1 中进行 任何 更改.您将面临以下错误。

Cannot convert the "X" value of type "X" to type "X".
At D:\temp\PSIssue\Script1.ps1:3 char:1
+ [X] $v = New-Object X
+ ~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : MetadataError: (:) [], ArgumentTransformationMetadataException
    + FullyQualifiedErrorId : RuntimeException

可以想象,PS 文件中的任何更改(即使您刚刚添加了空格)都会强制重新编译,因此类型 X 变得不同于 X 它曾经是 - 临时容器程序集已更改(在 .NET 中很容易重现同样的问题 - 只要 "Fully Qualified Assembly Names" 相同,类型就相同)。 Script1.ps1 中的更改使事情再次正常运行。

有什么办法可以解决这类问题吗?

我能够复制并解决您的问题。这类似于您在范围内定义 class 并尝试在同一范围内定义另一个 class。 class 定义保留在 PowerShell 会话中。在 Script1.ps1 中,您需要修改代码以不显式声明要键入的变量。只需如下使用即可不使用强类型并让 PowerShell 确定类型并动态分配它:

. $PSScriptRoot\Common.ps1

$v = New-Object X

现在您应该可以在 Common 中更改 class X 的定义。ps1 任意多次,而无需关闭和重新加载。

上面的示例使用“弱类型”您可以在此处阅读更多相关信息和其他详细信息:Variable Types and Strongly Typing