2

I can define an array as a generic list like this

$array = [Collections.Generic.List[String]]@()

And I can define an element in a hash table as an array like this

$hash = @{
   array = @()
}

But I can't define an element in a hash table as a Generic List, like this

$hash = @{
   array = [Collections.Generic.List[String]]@()
}

Instead I get this error

Cannot convert the "System.Object[]" value of type "System.Object[]" to type "System.Collections.Generic.List`1[System.String]

I have been using Generic Lists to avoid the (minor in my case, to be sure) performance issue with regularly adding to a standard array. But this is the first time I have needed to create a hash table that contains a generic list (for a complex return value). So, first question, is this is even possible? And second question, what is the difference under the hood between simply setting a variable and a hash table element?

EDIT: This is interesting. I CAN use

[System.Collections.ArrayList]@()

and it works. So, now I am curious what exactly is the difference between

[System.Collections.ArrayList]

and

[Collections.Generic.List[String]]

I guess this is the down side of being self taught. I found reference to [Collections.Generic.List[String]] on a BLOG, and maybe [System.Collections.ArrayList] is a much better answer? What I think I understand from this is that the former is specifically typed as a list of strings, while the latter is a list of generic objects, which then must be cast in use, which has potential bug and performance issues. Still, I wonder why the typed generic doesn't work in a hash table.

Gordon
  • 6,257
  • 6
  • 36
  • 89
  • 1
    Cannot reproduce on PowerShell 5, the statement works without error. What's your version? (`$PSVersionTable.PSVersion`) – Jeroen Mostert Sep 08 '17 at 11:50
  • 4
    What should work on all versions is `$hash = @{ array = New-Object System.Collections.Generic.List[String] }`. Slightly clumsier, of course. – Jeroen Mostert Sep 08 '17 at 11:53
  • Jeroen, I am indeed on v2, so that explains it. And I guess it makes some sense that the shorthand might not work, but the longhand approach does. Thanks! – Gordon Sep 08 '17 at 12:01
  • 2
    Your statement is not actually shorthand for the other one -- it converts an actual array (albeit an empty one) to a `List`. `New-Object` simply creates a new empty list directly. In PowerShell 2, I don't think there's a way to do the conversion instantly in one line. (I've tried, but it runs into all sorts of weird issues invoking the constructor that takes an `IEnumerable` when the array is not empty). Upgrading is highly recommended. :-) – Jeroen Mostert Sep 08 '17 at 12:09
  • Yeah, not a shortcut in the sense of an Alias. Just a less verbose approach. As for updating, I would love to be able to make that assumption, but my customers are Architects, who are notoriously tech phobic and cheap. So I need to support an unupdated Windows 7 for a few more years at least. :( – Gordon Sep 08 '17 at 12:49
  • To answer your other question: using `ArrayList` will generally pose less headaches because you avoid issues with generics, and PowerShell isn't much into strong typing to begin with, so the fact that it stores generic `Objects` and not typed `Strings` will rarely be an issue, while you still have the allocation performance benefits. You would only notice the difference between an `ArrayList` and `List` for value types (like `int`), because `ArrayList` boxes all the values into objects, while `List` does not. If that's important, though, you should probably be writing C# anyway. – Jeroen Mostert Sep 08 '17 at 13:32
  • Ah, so in the context of Powershell both are an improvement over +=, but [System.Collections.ArrayList] is superior to [Collections.Generic.List[String]]. Honestly in my case I doubt I can really make a good argument against +=, since we are talking about tens to maybe 100 items added to the array, as initialization of a process that can take hours to complete. So, really just me wanting to learn. And today was a school day! ;) – Gordon Sep 08 '17 at 14:09

0 Answers0