例如我想使用这个类 Microsoft.HyperV.PowerShell.HardDiskDrive
我尝试通过这种方式对其进行初始化:
$obbb = [Microsoft.HyperV.PowerShell.HardDiskDrive]@{
Path = 'D:\\TEST\\test\\Virtual Hard Disks\\test.vhdx'
DiskNumber = $null
MaximumIOPS = '1000'
MinimumIOPS = '0'
QoSPolicyID = '00000000-0000-0000-0000-000000000000'
SupportPersistentReservations = $false
WriteHardeningMethod = '0'
ControllerLocation = '0'
ControllerNumber = '0'
ControllerType = '0'
Name = 'Hard Drive on IDE controller number 0 at location 0'
PoolName = 'Primordial'
Id = 'Microsoft:480244F9-44D4-4BFC-B34B-EC3C425D52F7\\83F8638B-8DCA-4152-9EDA-2CA8B33039B4\\0\\0\\D'
VMId = '480244f9-44d4-4bfc-b34b-ec3c425d52f7'
VMName = 'test'
VMSnapshotId = '00000000-0000-0000-0000-000000000000'
VMSnapshotName = ''
CimSession = $null
ComputerName = 'NodeTest'
IsDeleted = $false
VMCheckpointId = '00000000-0000-0000-0000-000000000000'
VMCheckpointName = ''
}
但是得到了这个错误:
Cannot convert the "System.Collections.Hashtable" value of type "System.Collections.Hashtable" to type "Microsoft.HyperV.PowerShell.HardDiskDrive".
At line:1 char:1
+ $obbb = [Microsoft.HyperV.PowerShell.HardDiskDrive]@{
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [], RuntimeException
+ FullyQualifiedErrorId : ConvertToFinalInvalidCastException
我也尝试过不同的新对象变体 https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/new-object?view=powershell-6
但是出现错误。
有没有可能?
谢谢。
最佳答案
Maximilian Burszley在对该问题的评论中提供了关键指针:
PowerShell 的 哈希表构建技术仅当目标类型(也)具有 时才有效构造函数 那是:
您看到的错误消息暗示
[Microsoft.HyperV.PowerShell.HardDiskDrive]
没有这样的构造函数(有关如何检查构造函数,请参阅底部部分)。假设具有这种构造函数的类型具有 可设置的公共(public)属性 , 你可以 从条目匹配这些属性的任何子集的哈希表中强制转换 ,其中每个条目的键必须是此类属性的名称,其值必须是类型兼容的名称(已经与该属性具有相同类型或可转换为该属性)。
PowerShell 首先使用无参数构造函数实例化类型,然后设置哈希表中指定的公共(public)属性。
这是一个(有些人为的)示例:
$obj = [System.Exception] @{ # just [Exception] works too, because 'System.' is implied
HResult = 0x8000400
Source = 'SomeModule'
}
以上等价于:$obj = New-Object System.Exception; $obj.HResult = 0x8000400; $obj.Source = 'SomeModule'
由于需要无参数构造函数,哈希表技术目前主要用于 DTO - 像“财物袋” .
如果给定类型的所有公共(public)构造函数都有参数 ,哈希表技术不起作用,您必须 调用构造函数以实例化类型 - 通过静态
::new
方法 (PSv5+) 或通过 New-Object
小命令 ;例如,调用 (int year, int month, int day)
[System.DateTime]
的过载构造函数:New-Object DateTime -ArgumentList 2018, 12, 1 # '-ArgumentList' is optional
[DateTime]::new(2018, 12, 1) # PSv5+ equivalent
为了调用单参数构造函数,可以使用强制转换 - 请参阅下一节。但是,an enhancement is coming向 PowerShell 核心提示 TessellatingHeckler .
这将允许使用哈希表技术,即使具有参数的构造函数,只要哈希表条目集与给定的构造函数重载参数匹配。
通常,除了上面讨论的哈希表情况,强制转换 (
[<target-type>] <operand>
) 和隐式转换在以下情况下工作 , 按考虑顺序:此信息来自 PowerShell Core 的源代码 here .
(a) 如果目标类型用
TypeConverterAttribute
修饰指定自定义 TypeConverter
的属性或 PSTypeConverter
支持从操作数类型转换的类。或者,这些自定义转换器类可以通过 PowerShell 的 ETS(扩展类型系统),通过
Update-TypeData -TypeConverter
与类型相关联。 )(b) 如果目标类型支持静态
::Parse()
从字符串构造实例的方法:[DateTime] '2018-12-01'
# The above matches `::Parse()` overload `static datetime Parse(string s)`
# However, given that there's also an overload that accepts a
# System.IFormatProvider argument, PowerShell uses that in order
# to use *culture-invariant* parsing.
# Thus, the above is the equivalent of:
[DateTime]::Parse('2018-12-01', [cultureinfo]::InvariantCulture)
更多关于 PowerShell 使用不变区域性的信息可以在 this answer 中找到。 .(c) 如果目标类型有一个带有单个参数的公共(public)构造函数,该参数与操作数类型相同或兼容:
[Exception] 'Something failed'
# The above matches constructor `Exception(string message)` and is the
# equivalent of:
New-Object Exception -ArgumentList 'Something failed'
[Exception]::new('Something failed')
(d) 如果目标类型定义了隐式或显式 conversion operator对于操作数的类型。(e) 如果操作数类型实现
IConvertible
用于构造目标类型的等效实例的接口(interface)(仅限于 CLR 运行时类型(内置类型))。在 PSv5+ ,很容易检查给定(加载)类型的构造函数 :调用静态
::new
方法,不带括号,列出所有公开可用的构造函数的方法重载(签名);使用类型 [System.Random]
的示例:PS> [Random]::new
OverloadDefinitions
-------------------
System.Random new()
System.Random new(int Seed)
的存在|一个 new()
重载 - 无参数 - 是无参数公共(public)构造函数的证据 .如果根本没有输出,则暗示该类型没有任何公共(public)构造函数。
关于.net - 是否可以使用属性初始化 .NET 类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52031431/