为什么Get-Date似乎返回DateTime对象,但BinarySerializer指示它返回PSObject?

Jus*_*ing 5 powershell datetime binary-serialization psobject

拿简单的HashTable:

$data = @{
    First = 'Justin';
    Last = 'Dearing';
    StartDate = Get-Date '2002-03-23';
}
Run Code Online (Sandbox Code Playgroud)

关键的StartDate似乎包含DateTime.

C:\Users\zippy\Documents> $data.StartDate.GetType().FullName
System.DateTime
Run Code Online (Sandbox Code Playgroud)

但是,如果我尝试对其执行二进制序列化,我会得到一个例外,抱怨PSObject不可序列化.

$ms = New-Object System.IO.MemoryStream
$bf = New-Object System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
$bf.Serialize($ms, $data)
$ms.Close()
Run Code Online (Sandbox Code Playgroud)

抛出:

DocumentsException calling "Serialize" with "2" argument(s): "Type 'System.Management.Automation.PSObject' in Assembly 'System.Management.Automation, Versio
n=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' is not marked as serializable."
At C:\Users\jdearing\AppData\Local\Temp\b8967f99-0a24-41f7-9c97-dad2bc288bd9.ps1:12 char:14
+ $bf.Serialize <<<< ($ms, $data)
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException
Run Code Online (Sandbox Code Playgroud)

如果我使用显式转换为[DateTime],这条消息消失了,一切正常:

$data = @{
    First = 'Justin';
    Last = 'Dearing';
    StartDate = [DateTime] (Get-Date '2002-03-23');
}
Run Code Online (Sandbox Code Playgroud)

所以Get-Date并没有真正返回DateTime,或者是其他一些PowerShell奇怪的工作在这里.

CB.*_*CB. 5

基于msdn:

PSOobject类:封装Object类型的基础对象或键入PSCustomObject,以允许Windows PowerShell环境中任何对象的一致视图.

 ( get-Date '2002-03-23' ) -IS [psobject]
True

( get-Date '2002-03-23' ) -IS [datetime]
True

[datetime]( get-Date '2002-03-23' ) -IS [datetime]
True

[datetime]( get-Date '2002-03-23' ) -IS [psobject]
False
Run Code Online (Sandbox Code Playgroud)


x0n*_*x0n 3

PowerShell 中的每个对象实际上大部分都透明地包装在PSObject中。我之所以说“大部分是透明的”,是因为 PowerShell 中存在不少错误,它们在将对象泄漏到另一个 API 之前忽略了删除包装器。这会导致各种各样的问题,就像您现在看到的那样。在 connect.microsoft.com/powershell 中搜索 PSObject 包装器。我相信在使用基于DLR的新引擎的 v3 中这不再是问题。