irvnriir
irvnriir

Reputation: 806

Making .NET array type in Powershell

i'm trying to make System.Memory[char] .

[System.Memory[char]]::Memory([char],0,10) * says it can't find System.Memory type .

Also tried *

[System.Memory`3+[[char],0,10]]@()

Solution: The issue seems to be the .NET version used by the Powershell .

Upvotes: 4

Views: 406

Answers (1)

mklement0
mklement0

Reputation: 437998

It is the static pseudo method ::new(), introduced in PowerShell v5, that provides access to a type's constructors.[1]

# Initialize a [System.Memory[char]] instance with 10 NUL (0x0) chars,
# from a [char[]] array.
[System.Memory[char]]::new(
  [char[]]::new(10)
)

Note: The two System.Memory`1 constructors both require a [char[]] array as an argument. The two additional arguments in the 3-parameter overload, start and length, must refer to a range of elements within that array.

The above simply creates a 10-element array to begin with (implicitly using NUL characters), obviating the need for the additional arguments.

If you wanted the input array to use a given character other than NUL, you could use something like , [char] 'x' * 10:
, [char] 'x' create a single-element array with char. 'x', which * 10 then replicates to return a 10-element array. Note that the array will be [object[]]-typed, not [char[]]-typed, but it still works.


Note:

  • [System.Memory[char]]@() does not work, because in order for PowerShell to translate this cast to a single-parameter constructor call, the operand must be a [char[]] array:

    • [System.Memory[char]] [char[]] @()
  • Fundamentally, the System.Memory`1 type is available only in .NET Core 2.1+ / .NET 5+.

    • The simplest way to check if the type is available in your PowerShell session is if [bool] $IsCoreClr returns $true - in other words: you need to be running PowerShell (Core) 7+, the modern, cross-platform, install-on-demand edition of PowerShell.

[1] In earlier PowerShell versions you need to use the New-Object cmdlet, which uses argument(-parsing) mode, as all cmdlets do. As such, its syntax doesn't map cleanly onto the expression-mode syntax that is familiar from method/constructor calls, especially with respect to passing a single argument that is an array, as in this case:
New-Object System.Memory[char] -ArgumentList (, (New-Object char[] 10))
Note the need to wrap the array constructed by , [char] 0) * 10 in another array, namely a transitory one that is needed to make New-Object treat the original array as a single argument for the target constructor.
Additionally, ::new() performs better, though that will often not matter. See this answer for details.

Upvotes: 5

Related Questions