[MSH] How to a[void] returning multiple values from a function
I have succesfully made one of C# application I was working on at work to call MSH script on the fly during runtime. Everything seemed to have been working fine until I have encounted this problem that
MSH functions can return mutiple values I have passed a variable named
$arr of type
System.Collections.ArrayList to the Msh Script through
Runspace rs = RunspaceFactory.CreateRunspace();
rs.SessionStateProxy.SetVariable("arr", new ArrayList());
/*** snip ***/
string cmd = ". .\\parse-file.msh";
Pipeline pl = rs.CreatePipeline(cmd);
From here on, a variable named
$arr is visible in "parse-file.msh".
Now in "parse-file.msh" script, I tried something like(
NOTE: In actual "parse-file.msh", there is no initialization code for $arr to ArrayList, in the following function, $arr are initialized as a demonstrative purpose only, /\/\o\/\/, I have cleared it up here :))
MSH>function bar {
>> $arr = new-object System.Collections.ArrayList
>> $arr.Add(1)
>> $arr.Add(2)
>> $arr.Add(3)
>>
>> return $arr
>> }
>>
MSH>bar
0
1
2
1
2
3
And the function returns 4 values, 3 int32 values and 1 3-element ArrayList object, instead of just the contents of
$arr.
We can confirm that through the following snippet
MSH>function multiple-returns {
>> $arr = new-object System.Collections.ArrayList
>> $arr.Add(5)
>> $arr.Add(6)
>> $arr.Add(7)
>> return $arr}
>>
MSH>multiple-returns
0
1
2
5
6
7
MSH>$a, $b, $c, $d, $e = multiple-returns
MSH>$a
0
MSH>$b
1
MSH>$c
2
MSH>$d
5
6
7
MSH>$e
MSH>$d.getType().Name
ArrayList
MSH>$e.getType().Name
You cannot call a method on a null-valued expression.
At line:1 char:11
+ $e.getType( <<<< ).Name
First 3 return values(0, 1, 2) were caused by the fact that
ArrayList returns "index at which the value has been added".
Well, But then, what if you don't actually want to return indexes at which value has been added?
There are two choices(and as far as I understand, they work about the same although the background principle is different)
*EDIT*: there are 3 choices( Thanks
/\/\o\/\/ for another solution :), Check out "comments" section )
- [void]
- out-null
- > $null
[void] in front of a method indicates that, the method does not return a value.
For example, try out the following(yes, do try them out!)
MSH>[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
GAC Version Location
--- ------- --------
True v2.0.50727 C:\WINDOWS\assembly\GAC_MSIL\System.Windows.Forms\2.0.0.0__b77a5c561934e08...
MSH>[void][System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
MSH>[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | out-null
MSH>[System.Reflection.Assembly]::LoadWithPartialName("system.windows.forms") >$null
MSH>
Let's see what just happened
- Calling Assembly.LoadWithPartialName return the loaded assembly and the result is returned.
- Looking at the second "[void]Assembly.LoadWithPartialName", you can tell that it didn't return anything(although Assembly is still loaded)
- Third command also did not return anything(Well technically it did return something but it was sent to null)
- Fourth command, you are sending output to null in different fashion.
Now Let's revise the function "bar".
MSH>function bar {
>> $arr = new-object System.Collections.ArrayList
>> [void]$arr.Add(1)
>> [void]$arr.Add(2)
>> [void]$arr.Add(3)
>>
>> return $arr
>> }
>>
MSH>bar
1
2
3
MSH>function bar {
>> $arr = new-object System.Collections.ArrayList
>> $arr.Add(1) | out-null
>> $arr.Add(2) | out-null
>> $arr.Add(3) | out-null
>>
>> return $arr
>> }
>>
MSH>bar
1
2
3
Now those functions did not return added index positions during "ArrayList.Add" operations.
I tend to go with
[void] since it sounds technically right to mark(or cast, not sure about how to call it) a method as not returning any value
Tags :
Monad msh