Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 491
Eugene D. Gubenkov Avatar asked Apr 22 '16 22:04

Eugene D. Gubenkov


People also ask

How do I convert an object to a string in PowerShell?

The Out-String cmdlet converts input objects into strings. By default, Out-String accumulates the strings and returns them as a single string, but you can use the Stream parameter to direct Out-String to return one line at a time or create an array of strings.

What does :: mean in PowerShell?

From the about_Operators help topic: :: Static member operator Calls the static properties operator and methods of a .NET Framework class. To find the static properties and methods of an object, use the Static parameter of the Get-Member cmdlet. [

Which option is valid for datatype in PowerShell?

PowerShell data types include integers, floating point values, strings, Booleans, and datetime values. Variables may be converted from one type to another by explicit conversion, such as [int32]$value .


1 Answers

I was able to replicate and resolve your issue. It is similar to if you define a class in a scope and you try to define another class in the same scope. The class definition is retained in PowerShell session. In Script1.ps1 you need to modify the code to not explicitly declare the variable to type. Just use as below to not use Strong Typing and let PowerShell determine the type and assign it dynamically:

. $PSScriptRoot\Common.ps1

$v = New-Object X

Now you should be able to change the definition of class X in Common.ps1 as many times as you want without needing to close and reload.

The example above uses "Weak typing" You can read more about this and other details here: Variable Types and Strongly Typing

like image 112
Aman Sharma Avatar answered Oct 08 '22 08:10

Aman Sharma