Such a
PSObject
has the member
_immediateBaseObject
that contains a reference to the actual object, which can by any
.NET object, that is manipulated through the PowerShell object.
PSObject, its base object and PSCustomObject
In the
source code,
PSObject
has the following interesting snippets (
heavily redacted by me for brevity) that I believe shed some light on how
PSObject
and
PSCustomObject
play together.
In
PSObject
, the field
_immediateBaseObject
contains a reference to the object that a
PowerShell object is storing (via
PSObject
).
If the constructor of PSObject
is called with an object (public PSObject(object obj)
), the reference of _immediateBaseObject
is set to that object by calling CommonInitialization(obj)
.
However, if the constructor without argument (
public PSObject()
) is used to initialize a
PSObject
instance,
CommonInitialization()
is called with
PSCustomObject.SelfInstance
. This expression refers to the
PSCustomObject
singleton(?). Thus,
_immediateBaseObject
is initialized with a reference to
PSCustomObject
(see also
definition of PSCustomObject
).
In summary, PSCustomObject
is used to intialize the base object of PSObject
in absence of any other .NET object. This indicates that the PSObject
is just used to store one or more NoteProperty
(?).
public class PSObject : IFormattable, IComparable, ISerializable, IDynamicMetaObjectProvider
{
/// This is the main field in the class representing
/// the System.Object we are encapsulating.
private object _immediateBaseObject;
/// Initializes a new instance of PSObject with an PSCustomObject BaseObject.
public PSObject()
{
CommonInitialization(PSCustomObject.SelfInstance);
}
/// Initializes a new instance of PSObject wrapping obj (accessible through BaseObject).
public PSObject(object obj)
{
CommonInitialization(obj);
}
private void CommonInitialization(object obj)
{
if (obj is PSCustomObject)
{
this.ImmediateBaseObjectIsEmpty = true;
}
_immediateBaseObject = obj;
}
/// Gets the object we are directly wrapping.
/// If the ImmediateBaseObject is another PSObject,
/// that PSObject will be returned.
public object ImmediateBaseObject => _immediateBaseObject;
/// Gets the object we are wrapping.
/// If the ImmediateBaseObject is another PSObject, this property
/// will return its BaseObject.
public object BaseObject
{
get
{
object returnValue;
PSObject mshObj = this;
do
{
returnValue = mshObj._immediateBaseObject;
mshObj = returnValue as PSObject;
} while (mshObj != null);
return returnValue;
}
}
}
Public properties
The PSObject
class exhibits six public
properties:
// Gets the member collection.
public PSMemberInfoCollection<PSMemberInfo> Members …
// Gets the Property collection, or the members that are actually properties.
public PSMemberInfoCollection<PSPropertyInfo> Properties …
// Gets the Method collection, or the members that are actually methods.
public PSMemberInfoCollection<PSMethodInfo> Methods
// Gets the object we are directly wrapping.
// (If the ImmediateBaseObject is another PSObject, that PSObject will be returned.)
public object ImmediateBaseObject => _immediateBaseObject;
// Gets the object we are wrapping
// (If the ImmediateBaseObject is another PSObject, this property will return its BaseObject.)
public object BaseObject …
// Gets the type names collection initially containing the object type hierarchy.
public Collection<string> TypeNames …
PS C:\> $obj = get-date
PS C:\> $obj.psObject.Members
PS C:\> $obj.psObject.Properties
PS C:\> $obj.psObject.Methods
PS C:\> $obj.psObject.ImmediateBaseObject
PS C:\> $obj.psObject.BaseObject
PS C:\> $obj.psObject.TypeNames
TODO: fields
The class has also the following interesting fields that should eventually be described:
private WeakReference<TypeTable> _typeTable;
private AdapterSet _adapterSet;
private PSMemberInfoInternalCollection<PSMemberInfo> _instanceMembers;
private PSMemberInfoIntegratingCollection<PSMemberInfo> _members;
private PSMemberInfoIntegratingCollection<PSPropertyInfo> _properties;
private PSMemberInfoIntegratingCollection<PSMethodInfo> _methods;
private PSObjectFlags _flags;
PSMemberInfo
is the base class for all members of a
PSObject
.
PSPropertyInfo
is the base class for all members of a
PSObject
that behave like a property.
PSMethodInfo
is the base class for all members of a
PSObject
that behave like a method.