I agree that there can be a lot of confusion about this behaviour around
return type from a command. As I mentioned before, we reduce the collection
of one object to the object itself. This is one of the controversial
desisions we made. To resolve this dilemma as you mentioned below, @()
operator is introduced so that this reduction is not performed.
The best way to think of @() operator is to treat it as a conversion
operator. If it is applied to an collection, it will return that collection
itself. If it is applied to an object that is not a collection, it will wrap
it in an collection. What this means is that, (1,2,3), @(1,2,3),
@(@(1,2,3)), ..., will all result in the same array of 1,2,3. On the other
hand, @(1), will be an array including 1.
Comma (,) operator, on the other hand, is an array wrapping operator. An new
array is always created from this operator. As a result, ,1 is an array of
1. ,,1 is an array of array of 1, and so on.
--
George Xie [MSFT]
Microsoft Command Shell Development
Microsoft Corporation
This posting is provided "AS IS" with no warranties, and confers no rights.
"Mike Bridge bridgecanada _ com>" <mike -> wrote in message
news:376FEFF1-986D-419E-8596-70C412E692A2@microsoft.com...
> Hi-
>
> Sorry if I'm being thickheaded here, but I still don't see how I can
> generalize this to my original problem. If I apply this to the first post
> in
> this thread, I get this:
>
> PS> $a=,(get-process iexplore) #one element
> PS> $a=,(get-process svchost) #many elements
> PS > $a[0].gettype() | format-list BaseType
>
> BaseType : System.ComponentModel.Component
>
> PS > $b[0].gettype() | format-list BaseType
>
> BaseType : System.Array
>
> It appears to be impossible in the PowerShell to determine the return type
> (object vs. array) in advance without testing every single result in every
> call. As far as I can tell, I can't use any collection-based commands in
> a
> pipeline, because I can't show in advance what each command will return!
>
> I'm a big fan of the stuff you guys doing, but unless you can show me
> otherwise, I can't help but think that this is a significant defect in the
> PowerShell language definition, and a violation of both the
> object-oriented
> programming paradigm and the contract-programming paradigm.
>
> Thanks,
>
> -Mike
>
>
>
> "xshell" wrote:
>
>> Or you can just use the comma operator
>>
>> 40[~]> $a=1,2,3
>> 41[~]> $a.gettype().Name
>> Object[]
>> 42[~]> $b=3,4,5
>> 43[~]> $c=,$a,$b
>> 44[~]> $c.gettype().Name
>> Object[]
>> 45[~]> $c.Length
>> 2
>> 46[~]> $c[0]
>> 1
>> 2
>> 3
>> 47[~]> $c[1]
>> 3
>> 4
>> 5
>> 48[~]>
>>
>> "Mike Bridge bridgecanada _ com>" <mike -> wrote in message
>> news:FCA39337-0BC7-4924-9544-5FF9966611B4@microsoft.com...
>> > Hi-
>> >
>> > I had a closer look at this, and it's more confusing than I thought:
>> >
>> > PS> $a = @(1,2,3)
>> > PS> $b = @(3,4,5)
>> > PS> $c = @($a,$b)
>> > PS> $c.length
>> > 2
>> >
>> > ...but
>> >
>> > PS> $d = @(1,2,3)
>> > PS> $e = @($d)
>> > PS> $e.length
>> > 3
>> >
>> > It seems to me that due to the one-vs-many guesswork that's going on
>> > behind
>> > the scenes, you *can't* be sure that you're creating an array of arrays
>> > unless you wrap both these in the @() operator, i.e.:
>> >
>> > $c = @(@($a),@($b))
>> >
>> > Ugh!!
>> >
>> > -Mike
>> >
>> >
>> >
>> >
>> > But passing
>> >
>> >
>> > "George Xie [MSFT]" wrote:
>> >
>> >> It was a designed behaviour for powershell to reduce the output of a
>> >> collection of one object into the object itself. To force a collection
>> >> to
>> >> be
>> >> returned, you can use @() operator, as below
>> >>
>> >> PS> @(get-process iexplore)[0].Processname
>> >> IEXPLORE
>> >>
>> >> This operator will force an collection to be returned no matter
>> >> whether
>> >> the
>> >> number of output data is 0, 1 or many.
>> >>
>> >> It is also a designed behavior to return null when a non-existing
>> >> property
>> >> for an object is accessed. This allows a script to operate on
>> >> different
>> >> kind
>> >> of objects without having to throw a lot of errors. A lot of dynamic
>> >> language are using similiar kind of behaviour.
>> >>
>> >> --
>> >> George Xie [MSFT]
>> >> Microsoft Command Shell Development
>> >> Microsoft Corporation
>> >> This posting is provided "AS IS" with no warranties, and confers no
>> >> rights.
>> >>
>> >> "Mike Bridge bridgecanada _ com>" <mike -> wrote in message
>> >> news:46B5B1CC-4B29-4C86-BC41-1116A399A141@microsoft.com...
>> >> > Hi-
>> >> >
>> >> > I am confused about the behaviour of a collection with a single
>> >> > element
>> >> > vs.
>> >> > the behaviour of a collection with multiple elements. If I have a
>> >> > collection
>> >> > with one element, it gives me this:
>> >> >
>> >> > PS> (Get-Process iexplore).Processname
>> >> > IEXPLORE
>> >> > PS>
>> >> >
>> >> > But querying a collection of four elements gives me an empty result:
>> >> > PS> (Get-Process svchost).Processname
>> >> > PS>
>> >> >
>> >> > I would expect this to either return an error, or else give me a
>> >> > four-element list. I also see that this doesn't give me an error
>> >> > either:
>> >> >
>> >> > PS> (Get-Process svchost).Xwoeifjwoeifj
>> >> > PS>
>> >> >
>> >> > I'm not sure what to make of that---is that what it's supposed to
>> >> > do?
>> >> >
>> >> > Thanks!
>> >> >
>> >> > -Mike
>> >> >
>> >> >
>> >>
>> >>
>> >>
>>
>>
>>