2012-03-09 18 views
5

Weźmy prosty HashTable:Dlaczego Get-Date wydaje się zwracać obiekty DateTime, ale BinarySerializer wskazuje, że zwraca PSObject?

$data = @{ 
    First = 'Justin'; 
    Last = 'Dearing'; 
    StartDate = Get-Date '2002-03-23'; 
} 

Kluczem StartDate wydaje się zawierać DateTime.

C:\Users\zippy\Documents> $data.StartDate.GetType().FullName 
System.DateTime 

Jednakże jeśli próbuję wykonać serializacji binarnej na niej, otrzymuję wyjątek twierdząc, że nie jest możliwy do serializacji PSObject.

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

Zgłasza:

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 

Ten komunikat znika i wszystko działa, jeśli mogę użyć wyraźne zabarwienie [DateTime] tak:

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

Więc to Get-Date nie bardzo zwrócenie DateTime, lub jest tu kilka innych dziwactw.

+0

Myślę, że wszystko w PS domyślnie jest ustawione na 'PSObject', chyba że wyraźnie zdefiniujesz typ. Wykonuje dynamiczne konwersje typów danych, więc może zwracać ciąg, który interpretuje jako "System.Datetime" w czasie wykonywania. – JNK

+0

@JNK, ale dlaczego Object.GetType() interpretuje coś jako DateTime, że format binarny interpretuje jako PSObject? –

+0

To tylko zgadywanie, ale może dlatego, że jest interpretowane w czasie wykonywania (ponieważ używasz metody 'GetType()' obiektu PSObject) - format binarny jest klasą systemową, a nie klasą PS – JNK

Odpowiedz

3

Każdy obiekt w powłoce Powerhell jest owinięty przeważnie przezroczysto w psobject. Mówię przeważnie w sposób przejrzysty, ponieważ istnieje kilka błędów w powłoce, które pomijają opakowanie, zanim wyciekną obiekt do innego interfejsu API. Powoduje to różnego rodzaju problemy, podobne do tych, które teraz widzisz. Wyszukaj connect.microsoft.com/powershell na opakowaniu psobject. Uważam, że nie jest to już problem w wersji 3 z nowym silnikiem opartym na DLR.

+0

Po prostu uruchomiłem VirtualBox i kod działa. Dzięki za wytłumaczenie. –

+1

Oto kolejny przykład, w którym psobject przykręca rzeczy; http://stackoverflow.com/questions/837095/why-does-powershells-return-keyword-cause-type-errors – x0n

+0

dzięki za wskazanie tego. Interesujące czytanie. –

5

bazowa na MSDN:

PSOobject Klasa: obudowuje obiekt bazowy typu Object lub wpisz PSCustomObject celu umożliwienia konsekwentnego widzenia dowolnego obiektu w środowisku 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