How to convert PSCustomObject with additional props to a custom class

旧城冷巷雨未停 提交于 2021-01-27 20:10:12

问题


Is there a neat way to convert a PSCustomObject to a custom class as a function parameter in PowerShell 5.1? The custom object contains additional properties.

I'd like to be able to do something like this:

class MyClass {
    [ValidateNotNullOrEmpty()][string]$PropA
}

$input = [pscustomobject]@{
    PropA          = 'propA';
    AdditionalProp = 'additionalProp';
}

function DuckTypingFtw {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $True, Position = 0, ValueFromPipeline)] [MyClass] $myObj
    )
    'Success!'
}

DuckTypingFtw $input

Unfortunately, instead of Success!, I'm getting:

DuckTypingFtw : Cannot process argument transformation on parameter 'myObj'. Cannot convert value "@{PropA=propA; AdditionalProp=additionalProp}" to type "MyClass". Error: "Cannot convert the "@{PropA=propA; AdditionalProp=additionalProp}" value of
type "System.Management.Automation.PSCustomObject" to type "MyClass"." At C:\temp\tmp.ps1:23 char:15 + DuckTypingFtw $input + ~~~~~~ + CategoryInfo : InvalidData: (:) [DuckTypingFtw], ParameterBindingArgumentTransformationException + FullyQualifiedErrorId : ParameterArgumentTransformationError,DuckTypingFtw

If I comment out the AdditionalProp, everything works fine.

Basically, what I want to achieve, is to return an object from one function and pass it to a second function, at the same time ensuring that the second function's param has all expected properties.


回答1:


If you create a constructor for the MyClass class that accepts an pscustomobject and pass through the property then that should work:

class MyClass {
    MyClass([pscustomobject]$object){
        $this.PropA = $object.PropA
    }
    [ValidateNotNullOrEmpty()][string]$PropA
}

$input = [pscustomobject]@{
    PropA          = 'propA';
    AdditionalProp = 'additionalProp';
}

function DuckTypingFtw {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $True, Position = 0, ValueFromPipeline)] [MyClass] $myObj
    )
    'Success!'
}

DuckTypingFtw $input

edit: If you want to also use MyClass somewhere else, add a default constructor for MyClass like:

class MyClass {
    MyClass() { } 
    MyClass([pscustomobject]$object){
        $this.PropA = $object.PropA
    }
    [ValidateNotNullOrEmpty()][string]$PropA
}



回答2:


In your code you define two properties for the custom object but one for the class. That's why you need either:

  • to add AdditionalProp in your class
  • to remove AdditionalProp from your PsCustomObject

The conversion is not possible by design.



来源:https://stackoverflow.com/questions/58330233/how-to-convert-pscustomobject-with-additional-props-to-a-custom-class

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!