Arguments as an array

Arguments for constructors can be passed in as an array. Each of the following may be used to create an instance of a StringBuilder object:

$argumentList = 'Initial value', 50 
$stringBuilder = New-Object System.Text.StringBuilder -ArgumentList $argumentList 
$stringBuilder = New-Object System.Text.StringBuilder($argumentList) 

Attempting to pass in a list of arguments using the new method will produce a different result; the initial string will be filled with both values:

PS> $argumentList = 'Initial value', 50
$stringBuilder = [System.Text.StringBuilder]::new($argumentList)

Write-Host $stringBuilder.ToString() -ForegroundColor Green
$stringBuilder
Initial value 50
Capacity MaxCapacity Length
-------- ----------- ------
16 2147483647 16

An array may be passed in using new, by using a slightly different approach:

$stringBuilder = [System.Text.StringBuilder]::new.Invoke($argumentList)
Write-Host $stringBuilder.ToString() -ForegroundColor Green
$stringBuilder
Initial value
Capacity MaxCapacity Length
-------- ----------- ------
50 2147483647 13

The ability to push arguments into an array presents a complication when an argument is an array. For example, the MemoryStream (System.IO.MemoryStream) class has a number of constructors; two of these expect an array of bytes, as shown in the following screenshot:

The first of these only expects an array (of bytes) as input. The following example shows an error generated when attempting to pass in the array:

PS> [Byte[]]$bytes = 97, 98, 99
$memoryStream = New-Object System.IO.MemoryStream($bytes)
New-Object : Exception calling ".ctor" with "3" argument(s): "Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection."
At line:2 char:17
+ $memoryStream = New-Object System.IO.MemoryStream($bytes)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [New-Object], MethodInvocationException
+ FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand

PowerShell is treating each byte as an individual argument for the constructor, rather than passing all of the values into the intended constructor.

The new static method does not suffer from this problem:

[Byte[]]$bytes = 97, 98, 99 
$memoryStream = [System.IO.MemoryStream]::new($bytes) 

To work around the problem in earlier versions of PowerShell, the unary comma operator may be used as follows:

$memoryStream = New-Object System.IO.MemoryStream(,$bytes) 

Using the comma operator prevents PowerShell from expanding the array into a set of arguments. The array held in bytes is wrapped in another array which contains a single element. When PowerShell executes this, the wrapper is discarded, and the inner-array (bytes) is passed without further expansion.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.223.213.238