.net - 是否可以使用属性初始化 .NET 类型?

标签 .net powershell constructor initialization hashtable

例如我想使用这个类 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/

    相关文章:

    .net - 适用于 .NET 的 SMTP 和 IMAP 服务器库

    string - 从PS命令Get-ADUser剪切字符串前后的所有内容

    java - 使用 Intellij 在 Java 中重构构造函数

    c# - ToString() 方法的意义是什么?

    c# - 不用 goto 编写重试逻辑的更好方法

    .net - 为什么 WinForms Control.Bottom 和 Control.Right 是只读的?

    powershell - 比较字符串数组并在与Out-GridView匹配时显示结果?

    python - 如何使用 youtube-dl 的 --add-header 选项?

    PHP - 扩展的 __construct

    c++ - 如何使C++构造跟踪类带参数?