4

As the title suggests I am trying to reference a Nested Generic Type in Powershell Core.

I found that the + sign is used instead of the . for accessing a nested type in Powershell... but the syntax doesn't seem to work for "Nested Generic Types"... the compiler doesn't like the code an errors about the syntax.

Special use of plus (+) sign in Powershell

Has anyone been successful in getting this to work or is it a known limitation?

[System.Collections.Generic.Dictionary[[string], [int]]+Enumerator] GetEnumerator()
  • 2
    It looks like the syntax might be ```[System.Collections.Generic.Dictionary`2+Enumerator[[String],[Int32]]]::new()``` but it doesn't work. `InvalidOperation: An error occurred while enumerating through a collection: Object reference not set to an instance of an object..` (I found this by newing up a dictionary, getting the enumerator and checking it's type info.) – Daniel Jul 20 '21 at 01:07
  • 1
    Thanks... that actually worked for me... I was able to define the appropriate method signature using that syntax. I didn't call `::new()` but instead called `.GetEnumerator()` on the underlying dictionary implementation – Sac Valley Tech Jul 20 '21 at 01:16

1 Answers1

0

Daniel has provided the solution:

[System.Collections.Generic.Dictionary`2+Enumerator[string, int]]

returns the type of interest (note that the nested [...] around the individual generic type arguments, string and int, are optional).

That is, before being able to specify type arguments in order to construct a generic type, you must first specify its open form, which requires specifying the generic arity (the count of type arguments, <n>) in the form `<n> following the type name, namely `2 in the case of System.Collections.Generic.Dictionary<TKey,TValue> (expressed in C# notation), using the language-agnostic .NET API notation, as explained in this answer.

  • If no nested type (suffixed with +<typename>) is involved, specifying the arity is optional if all type arguments are specified; e.g., instead of [System.Collections.Generic.Dictionary`2[string, int]], [System.Collections.Generic.Dictionary[string, int]] is sufficient.

However, the enumerator type in question has no public constructor, so you cannot instantiate it directly; rather, it is the type returned when you call .GetEnumerator() on (a constructed form of) the enclosing type, [System.Collections.Generic.Dictionary`2]; verify with:
Get-Member -InputObject ([System.Collections.Generic.Dictionary[string, int]])::new().GetEnumerator()

mklement0
  • 382,024
  • 64
  • 607
  • 775