Reputation: 60918
Starting from this Question I discovered that using the powershell.exe.config
to load .net Framework 4.0 runtime, this code:
$word = "Thisisatest"
[System.String]::Join("-", $word.ToCharArray())
return System.Char[]
Executing Powershell w/o powershell.exe.config
the same code works in the right way.
Someone can reproduce this issue and explain why??
My box is windows 7 pro with Powershell 2.0
Edit: my powershell.exe.config
<?xml version="1.0"?>
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0.30319"/>
<supportedRuntime version="v2.0.50727"/>
</startup>
</configuration>
Upvotes: 2
Views: 904
Reputation: 13432
This is due to the new overloads to string.Join
added in version 4 of the .NET framework:
PS> [Environment]::Version.ToString()
2.0.50727.5456
PS> [string]::Join.OverloadDefinitions
static string Join(string separator, string[] value)
static string Join(string separator, string[] value, int startIndex, int count)
PS> [Environment]::Version.ToString()
4.0.30319.269
PS> [string]::Join.OverloadDefinitions
static string Join(string separator, Params string[] value)
static string Join(string separator, Params System.Object[] values)
static string Join[T](string separator, System.Collections.Generic.IEnumerable[T] values)
static string Join(string separator, System.Collections.Generic.IEnumerable[string] values)
static string Join(string separator, string[] value, int startIndex, int count)
string[]
as the second argument, so each character from $word.ToCharArray()
is coerced to a string.
PS> Trace-Command *Member* { [string]::Join( "-", $word.ToCharArray() ) } -PSHost
...
MemberResolution: Method argument conversion.
MemberResolution: Converting parameter "-" to "System.String".
MemberResolution: Method argument conversion.
MemberResolution: Converting parameter "System.Char[]" to "System.String[]".
MemberResolution: Calling Method: static string Join(string separator, string[] value)
In .NET 4, the object[]
overload is preferred. Rather than boxing each character, the entire array is coerced to an object, sending a single-element object array to string.Join
, which then has ToString
called to produce the "System.Char[]"
output.
Method argument conversion.
Converting parameter "-" to "System.String".
Method argument conversion.
Converting parameter "System.Char[]" to "System.Object".
Method argument conversion.
Converting parameter "System.Object[]" to "System.Object[]".
Calling Method: static string Join(string separator, Params System.Object[] values)
To get the old behavior, you can insert a [string[]]
cast to influence how the method is resolved (or in this case just use PowerShell's -join
operator, which works correctly everywhere :).
PS> $word = 'test'
PS> [string]::Join( '-', $word.ToCharArray() )
System.Char[]
PS> [string]::Join( '-', [string[]]$word.ToCharArray() )
t-e-s-t
PS> [char[]]$word -join '-'
t-e-s-t
Upvotes: 2
Reputation:
Use the solution I provided in the other question. That is the PowerShell supported method of achieving what you want to do:
"Thisisatest".ToCharArray() -join '-'
http://technet.microsoft.com/en-us/library/dd315375.aspx
Upvotes: 0