What is it that you want to accomplish with this code? You can simply do $boundParameters = $PSBoundParameters, but both variables will refer to the same Dictionary (technically, [System.Management.Automation.PSBoundParametersDictionary). Adding or removing keys / values from one dictionary would affect the other.
Assuming you got the CopyTo function working, you’d have one object ($PSBoundParameters) that’s still a dictionary, and one that’s just an array of key/value pairs, but they’d still refer to the same Value objects. Changes made from one place or the other might affect both, depending on the types of objects stored in the dictionary.
In any case, the reason you’re having trouble is because that method is an explicit interface implementation, and working with those is a bit of a pain in PowerShell. I tried to get it working this morning, but haven’t quite got there yet for some reason; here’s my current test code:
function Test
{
param (
$FirstArg, $SecondArg, $ThirdArg
)
$boundParameters = New-Object -TypeName 'System.Collections.Generic.KeyValuePair`2[System.String,System.Object][]' -ArgumentList $PSBoundParameters.Count
$boundParameters.GetType().FullName
$type = [System.Collections.Generic.ICollection[System.Collections.Generic.KeyValuePair[String,Object]]]
$method = $type.GetMethod('CopyTo')
$method.GetParameters()
$arguments = [Object[]]($boundParameters, 0)
$method.Invoke($PSBoundParameters, $arguments)
}
Test 1 2 3
</pre>
You can find some more information on this topic at <a href="http://www.vistax64.com/powershell/169391-access-interfaces-members-net-object.html" target="_blank">http://www.vistax64.com/powershell/169391-access-interfaces-members-net-object.html</a>. Right now, I'm getting the error 'Exception calling "Invoke" with "2" argument(s): "Object of type 'System.Management.Automation.PSObject' cannot be converted to type 'System.Collections.Generic.KeyValuePair`2[System.String,System.Object][]'."' I'm not sure why, as I'm outputting the type of $boundParameters earlier in the function, and it's not a PSObject.
As a workaround, you could just create the copy yourself, ie:
function Test
{
param (
$FirstArg, $SecondArg, $ThirdArg
)
$boundParameters = New-Object -TypeName 'System.Collections.Generic.KeyValuePair`2[System.String,System.Object][]' -ArgumentList $PSBoundParameters.Count
$i = 0
foreach ($pair in $PSBoundParameters.GetEnumerator())
{
$boundParameters[$i++] = $pair
}
$boundParameters
}
Test 1 2 3
I don’t think CopyTo() will get you what you want. That will result in an array of KeyValuePair objects, i.e. not a lookup dictionary.
If that is indeed what you want, Dave is correct about why it does not work. The Dictionary class implements the CopyTo method explicitly which basically makes it a private method. Therefore, it just needs to be cast to an ICollection. Also, the destination array needs to be allocated first.