gpt4 book ai didi

powershell - 如果没有显式强制转换,对象会被包装在 PSObject 中

转载 作者:行者123 更新时间:2023-12-04 01:18:20 29 4
gpt4 key购买 nike

当显式转换我的新对象时(参见第一行代码),我新创建的 EntityReference 被存储而没有被包裹在 PSObject 中。 ,所以序列化它工作得很好:

$entityRef1 = [Microsoft.Xrm.Sdk.EntityReference](new-object Microsoft.Xrm.Sdk.EntityReference("businessunit", [System.Guid]::NewGuid()))
$unit = new-object Microsoft.Xrm.Sdk.Entity("businessunit")
$unit.Attributes["parentbusinessunitid"] = $entityRef1
$unit.Attributes["parentbusinessunitid"].GetType() # Produces "EntityReference"

# Serialize $unit including the entityRef, and write its xml representation
$serializer = New-Object System.Runtime.Serialization.DataContractSerializer($unit.GetType())
$stream = New-Object System.IO.MemoryStream
$serializer.WriteObject($stream, $unit)
$stream.Flush()
$stream.Seek(0, [System.IO.SeekOrigin]::Begin)
$reader = New-Object System.IO.StreamReader($stream)
$reader.ReadToEnd()
但是,当我不使用类型转换时:
$entityRef1 = (new-object Microsoft.Xrm.Sdk.EntityReference("businessunit", [System.Guid]::NewGuid()))
当我想序列化它时,PowerShell 会提示: Exception calling "WriteObject" with "2" argument(s): "Type 'System.Management.Automation.PSObject' with data contract name 'PSObject:http://schemas.datacontract.org/2004/07/System.Management.Automation' is not expected. 现在,我已阅读 Why does Get-Date seem to return DateTime objects, but the BinarySerializer indicate it returns a PSObject? ,看来这是同一个问题....
除了 我使用 PowerShell 3.0 ( $PSVersionTable.psversion 生成版本 3.0.-1.-1)并且该帖子中的“错误”代码片段在我的 PowerShell 环境中运行良好......
在那篇文章中建议使用新的 DLR基于 PowerShell 3 的引擎应该不再导致这些问题,所以他们对此过于乐观,还是我遇到了其他问题?

编辑 :下面的代码产生相同的行为,而不依赖于 CRM SDK。使用类型转换,PowerShell 提示无法序列化 System.UriBuilder ,而没有类型转换,它提示得到 System.Management.Automation.PSObject实例:
# $uriBuilder = [UriBuilder](New-Object UriBuilder)
$uriBuilder = (New-Object UriBuilder)

$dict = new-object Hashtable
$dict["mykey"] = $uriBuilder
$dict["mykey"].GetType() # Produces "UriBuilder"

# Serialize $dict including the uriBuilder, and write its xml representation
$serializer = New-Object System.Runtime.Serialization.DataContractSerializer($dict.GetType())
$stream = New-Object System.IO.MemoryStream
$serializer.WriteObject($stream, $dict)
$stream.Flush()
$stream.Seek(0, [System.IO.SeekOrigin]::Begin)
$reader = New-Object System.IO.StreamReader($stream)
$reader.ReadToEnd()

最佳答案

是的,这是另一个 PSObject展开错误,尽管在我思考之后,我意识到 PowerShell 团队知道它并且可能会在一段时间内保持“不会修复”。
在你诅咒它们之前,请考虑一下:当 PSObject(所有隐式类型)被传递给 .NET 方法时,它们被绑定(bind)器解包,但它不会递归到可枚举或检查属性以查看是否需要解包或不是。坦率地说,此时它无法知道类型为包含 PSObject 的对象(例如)的属性是否应该被解包,所以它什么也不做。如果需要,仅展开第一级实例。
我认为这里真正的错误是 uribuilder 实例在分配给哈希表键时没有被解包。
黄金法则:如果分配目标是对象,PowerShell 永远不会打开 PSObject。
因此,解决方法要么在创建时强制转换,要么在分配点强制转换:

$ht["foo"] = [uribuilder]$builder
New-Object cmdlet 是包装的原因。一旦 cmdlet 将实例传递给 PSCmdlet.WriteObject,就会应用包装器。

关于powershell - 如果没有显式强制转换,对象会被包装在 PSObject 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21389880/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com