8

私は PowerShell のクラスを使用しようとしています。これは、関連するデータをグループ化する非常に便利な方法であり、動作を処理するのが非常に面倒です。簡単なシナリオ: クラスを定義する 1 つの PS スクリプトと、そのクラスを使用する別のスクリプト。

共通.ps1

class X
{
    [string] $A
} 

Script1.ps1

. $PSScriptRoot\Common.ps1

[X] $v = New-Object X

で変更Script1.ps1を加えるまでは、すべて問題ありません。何回でも問題なく実行できますCommon.ps1。次のエラーが発生します。

タイプ "X" の "X" 値をタイプ "X" に変換できません。
D:\temp\PSIssue\Script1.ps1:3 文字:1
+ [X] $v = 新しいオブジェクト X
+ ~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : MetadataError: (:) []、ArgumentTransformationMetadataException
    + FullyQualifiedErrorId : RuntimeException

おそらく、PS ファイルに(空白を追加しただけでもX) 何らかの変更が加えられると、その再コンパイルが強制されるため、その型は以前とは異なりXます - 一時的なコンテナー アセンブリが変更されました (まったく同じ問題が .NET で簡単に再現可能です - 型は「完全修飾アセンブリ名」が同じである限り)。変更するとScript1.ps1、物事が再び正常に機能します。

このような問題を克服する方法はありますか?

4

1 に答える 1

4

問題を再現して解決することができました。これは、スコープ内でクラスを定義し、同じスコープ内で別のクラスを定義しようとする場合と似ています。クラス定義は PowerShell セッションに保持されます。Script1.ps1 では、変数の型を明示的に宣言しないようにコードを変更する必要があります。厳密な型指定を使用せず、PowerShell に型を決定させて動的に割り当てるには、以下のように使用してください。

. $PSScriptRoot\Common.ps1

$v = New-Object X

これで、Common.ps1 のクラス X の定義を何度でも変更できるようになりました。閉じて再読み込みする必要はありません。

上記の例では、「弱い型付け」を使用しています。これおよびその他の詳細については、変数の型と厳密な型付けを参照してください。

于 2016-04-23T15:15:17.267 に答える