I fully understand that a System.Array is immutable.
Given that, why does it have an Add() method?
It does not appear in the output of Get-Member.
$a = @('now', 'then') $a.Add('whatever')
Yes, I know this fails and I know why it fails. I am not asking for suggestions to use
IList, which is an interface that also covers resizable collections, may be surprising - it sounds like there are historical reasons for it.
In C#, this surprise is hard to stumble upon, because you need to explicitly cast to
IList or use an
IList-typed variable in order to even access the
By contrast, since version 3, PowerShell surfaces even a type's explicit interface implementations as direct members of a given type's instance. (Explicit interface implementations are those referencing the interface explicitly in their implementation, such as
IList.Add() rather than just
As a byproduct of this design, in PowerShell the
.Add() method can be called directly on
System.Array instances, which makes it easier to stumble upon the problem, because you may not realize that you're invoking an interface method. In the case of an array, the
IList.Add() implementation (rightfully) throws an exception stating that
Collection was of a fixed size; the latter is an exception of type
NotSupportedException, which is how types implementing an interface are expected to report non-support for parts of an interface.
What helps is that the
Get-Member cmdlet and even just referencing a method without invoking it - simply by omitting
() - allow you to inspect a method to determine whether it is native to the type or an interface implementation:
PS> (1, 2).Add # Inspect the definition of a sample array's .Add() method OverloadDefinitions ------------------- int IList.Add(System.Object value)
As you can see, the output reveals that the
.Add() method belongs to the