I'm just starting to learn some basics of PowerShell and can't get my head around New-Object and type casting. For example this:
# all of these yield the same
New-Object System.Net.Sockets.TcpListener -ArgumentList 5000
New-Object System.Net.Sockets.TcpListener(5000)
[System.Net.Sockets.TcpListener]500 # this works
# all of these yield the same
New-Object -TypeName System.Net.Sockets.TCPClient -ArgumentList "8.8.8.8", 53
New-Object System.Net.Sockets.TCPClient("8.8.8.8", 53)
[System.Net.Sockets.TCPClient]::New("8.8.8.8", 53)
# but this doesn't work
# [System.Net.Sockets.TCPClient]("8.8.8.8", 53) # does not work
-ArgumentList and using (arg1,...)? Is it that the name of the type and the (arg1,...) are interpreted as two different arguments to New-Object even when there is no space between them, and so the (arg1,...) is assigned as the value of -ArgumentList?System.Net.Sockets.TCPClient? The only difference I see is that it takes multiple arguments, whereas System.Net.Sockets.TcpListener takes a single argument. But why can PowerShell cast an integer to a System.Net.Sockets.TcpListener but not an array to a System.Net.Sockets.TCPClient by calling its constructor? I.e. why aren't these two equivalent:
[System.Net.Sockets.TCPClient]::New("8.8.8.8", 53) # works[System.Net.Sockets.TCPClient]("8.8.8.8", 53) # does not workWhat is the difference between using
-ArgumentListand using(arg1, ...)?
Do not use (arg1,...) it is pseudo method syntax that only happens to work - see the bottom section of this answer.
Instead, use arg1, ... - no parentheses, whitespace before the list; that is the positionally implied equivalent of -ArgumentList arg1, ... (or -Args arg1, ...)
Why doesn't casting work for the second example of
System.Net.Sockets.TCPClient?
Casting only works in two variants (leaving PowerShell's built-in type conversions, such as between numeric types, aside):
Casting from an object whose type matches a public, single-parameter constructor of the target type or, in the case of a string argument, if the target type has a static ::Parse([string]) method.
Casting from a hash table (@{ ... }) whose entries' keys match properties of the target type and assuming that the target type has a parameterless public constructor.
Therefore you cannot cast from an array of values (however, you can use array casts to construct multiple instances of the target type, e.g. [datetime[]] @('1 Jan', '2 Jan')
See this answer for more information.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With