.net - Difference between @($null) and $null -
i have powershell code invoking .net method expects class passed parameter.
the method accepts null value parameter, , in c# you'd call follows:
var t = new foo(null)
if translating powershell, 1 try:
$t = new-object foo($null)
but returns following error
new-object : constructor not found. cannot find appropriate constructor type foo
funilly enough, exact same error returned if call as:
$t = new-object foo
so first question why? .net see $null
absence of something, oppose type null
.net? why 2 instructions above return same error?
now, found way around problem follows:
$t = new-object foo(@($null))
this works fine, but... why?
(@($null)).gettype()
returns object[]
(@()).gettype()
return object[]
, if run:
$t = new-object foo(@())
i still get:
new-object : constructor not found. cannot find appropriate constructor type foo
so, second question: difference between @(), @($null) , $null?
also, , last question, else don't understand.
let's have .net method bar(string, foo)
if call:
$b = new-object bar("s", $null)
this works fine, without having convert object[] or alike.
so third , last question is: why number of parameters affect whether needs passed array or not?
my guess if cast array call as
$b = new-object bar(@("s", $null))
meaning though method expects 2 parameters, i'm passing 1 array of objects , automatically maps each of array items onto parameters, still doesn't quite provide answer first 2 questions :)
edit
i know @() empty array , @($null) array 1 element happens null, that's not i'm asking.
however, if calling:
$t = new-object foo($null)
makes foo's constructor see no parameter being passed, why calling @()
vs calling @($null)
differ? surely @($null)
should same @()
in case, absence of parameter gets seen in .net method.
why $null
mean , nothing @ all?
based on edit, have understanding of differences between $null , @($null).
unlike normal call .net method, calling constructor requires calling new-object cmdlet first. syntax new-object is:
new-object [-typename] <string> [[-argumentlist] <object[]>] [-property <idictionary>]
let's think moment how new-object works. using reflection, new-object call typename.getconstructors() , find candidate constructors can accept n arguments n number of arguments in argumentlist.
if call new-object this:
new-object -typename foo
then argumentlist has value $null. didn't pass $null, that's it's value anyway. if argumentlist $null, there no arguments. in example, that's obvious, didn't specify -argumentlist. if write:
new-object -typename foo -argumentlist $null
this ends same end result - no argument list. argumentlist expects [object[]], , $null valid value [object[]], means there no arguments.
if write:
new-object -typename foo -argumentlist @($null)
now passing [object[]] single value, value $null, , works expect.
this undoubtedly confusing, helps think of how might implement own c# function calls function , accepts param array. if param array null, received no arguments.
new-object can more confusing in cases. tripped overloaded constructors, 1 taking array, other taking multiple arguments. in c#, constructors like:
foo(object[] array); // #1 foo(string s, int i); // #2
and incorrect attempt call constructor #1:
new-object -typename foo -argumentlist @($array)
this calls constructor #2 because new-object expects [object[]] pass multiple arguments , want call constructor single array argument. correct powershell be:
new-object -typename foo -argumentlist (,$array)
because of confusion, added new way call constructors in powershell v5. it's available preview (http://www.microsoft.com/en-us/download/details.aspx?id=42936), syntax looks static method call:
[foo]::new($name, $count)
with new syntax, calling constructors no longer confusing, , side benefit, it's order of magnitude faster calling new-object.
edit: corrected example overloaded constructors.
Comments
Post a Comment