Powershell: Type [System.Management.Automation.PSMemberInfoIntegratingCollection`1] returned by .psobject.properties should have a .Count property

Created on 17 Mar 2019  路  11Comments  路  Source: PowerShell/PowerShell

Accessing .psobject.properties on any object is a convenient way to reflect on that object's properties.

Sometimes all you want is to _count_ the number of properties.

That is currently complicated by the [System.Management.Automation.PSMemberInfoIntegratingCollection[System.Management.Automation.PSPropertyInfo]] instance returned not implementing a .Count property.

The workaround is to wrap the .psobject.properties access in @(...) before accessing .Count, but that shouldn't be necessary.

Steps to reproduce

$obj = [pscustomobject] @{ one = 1; two = 2 }
$obj.psobject.properties.Count

Expected behavior

2

Actual behavior

1
1

That is, in the absence of a .Count property on the _collection_, member enumeration was used to look for a .Count property _on each element_ of the collection, which - due to PSv3+ implementing .Count even on _scalars_ - returned 1 for each property.

Environment data

PowerShell Core 6.2.0-rc.1
Windows PowerShell v5.1 
Issue-Question WG-Engine

Most helpful comment

Really you could just add

public int Count => System.Linq.Enumerable.Count(this);

To PSMemberInfoCollection<> just to fix this scenario as it's pretty annoying to run into. Not many folks are likely to though.

All 11 comments

Actually it is not Collection - it is IEnumerable.
```c#
internal class PSMemberInfoIntegratingCollection : PSMemberInfoCollection, IEnumerable where T : PSMemberInfo

public abstract class PSMemberInfoCollection : IEnumerable where T : PSMemberInfo
```

Yes, @iSazonov, but given its purpose - and, not least, its _name_,

PSMemberInfoIntegratingCollection
- it's reasonable to expect a .Count property, whether as a direct property or via an interface.

We could implement the class based on Collection. I am afraid that it is too expensive to use in PSObject. We need to avoid every extra byte.

Don't _most_ IEnumerables have a Count property anyway? Why is it lacking on here?

@vexx32: IEnumerable is about _lazy_ enumeration, so the count isn't known in advance - that's why the interface has no .Count property (applies to both the generic and the non-generic interface).

Really you could just add

public int Count => System.Linq.Enumerable.Count(this);

To PSMemberInfoCollection<> just to fix this scenario as it's pretty annoying to run into. Not many folks are likely to though.

I'm down.

I believe the property store could be refactored as a whole (for performance).
/cc @powercode

@iSazonov Yes, I've two different branches on separate approaches for that. But it is non-trivial.

@powercode You could share the code - somebody could help (Dongbo :-) ).

@iSazonov Waste of his time so far.

Was this page helpful?
0 / 5 - 0 ratings