8

I'm trying to use PowerShell's classes that is very handy way of grouping related data together and facing quite tedious to deal with behavior. The simplified scenario: one PS script that defines class and another script that uses that class.

Common.ps1

class X
{
    [string] $A
} 

Script1.ps1

. $PSScriptRoot\Common.ps1

[X] $v = New-Object X

Everything is good - you can run Script1.ps1 arbitrary amount of times with no issues - until you make any change in Common.ps1. You will face the following error.

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

Conceivably any change (even if you just added whitespace) in PS file forces its recompilation, so that type X becomes different than X it used to be - temporary container assembly has been changed (the very same issue easily reproducible in .NET - types are identical as long as "Fully Qualified Assembly Names" are the same). Change in Script1.ps1 makes things function normally again.

Is there any way to overcome such kind of issues?

4

1 回答 1

4

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

. $PSScriptRoot\Common.ps1

$v = New-Object X

现在您应该能够根据需要多次更改 Common.ps1 中类 X 的定义,而无需关闭并重新加载。

上面的示例使用“弱类型”您可以在此处阅读有关此内容和其他详细信息的更多信息:变量类型和强类型

于 2016-04-23T15:15:17.267 回答