Author Posts

March 11, 2016 at 12:32 pm

The question is simple, but I'm not sure if the answer is. What happens on the second line here?

$var = 1.5
[string] $var

One could think that the variable is cast. But the System.Double and System.String isn't based on each other so that wouldn't work in this case.

Or one could think that the ToString method of System.Double is called, but this is not the case. If you're using a language that uses period as it's decimal separator you might not have noticed this. I'm norwegian and therefore use the nb-NO culture. With this culture the following:

$var = 1.5
[string] $var

Will output:
(This could give you an headache since you'll get 15 if you run "[int] $var.ToString()")

So what happens? In which cases will "[someclass] $somevar" work and what is actually happening?

March 11, 2016 at 12:36 pm

It is converting the value to a string, but PowerShell's type conversion logic goes way beyond simple casting that would be available in a C# or other .NET app. Check out this blog post from the PowerShell team for more details on all the work that it does for you:

Understanding PowerShell's Type Conversion Magic

March 14, 2016 at 3:11 am

Thanks @dlwyatt

That post is actually quite helpful. Do you know if it's still up to date? This isn't documented on technet?

March 14, 2016 at 4:29 am

I'm not sure if it's still up to date. However, I poked around a bit, and it looks like this logic is just about completely found in the class [System.Management.Automation.LanguagePrimitives] , in the System.Management.Automation assembly. ([string]$var) seems to be the equivalent if ([System.Management.Automation.LanguagePrimitives]::ConvertTo($var, [string])), and if you're really interested in seeing under the hood, you can take a look at the implementation by opening that assembly in something like ILSpy or dotPeek. 🙂

March 14, 2016 at 4:45 am

Also, specifically for numbers, I found that this is what's happening for numeric to string conversions:

result = (string)Convert.ChangeType(valueToConvert, resultType, CultureInfo.InvariantCulture.NumberFormat);

So that's why you're seeing a difference in output between ([string]$var) and ($var.ToString()) ; with the [string] "cast", PowerShell is hard-coded to use InvariantCulture instead of CurrentCulture.