.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