定义自定义Powershell对象

时间:2016-06-08 00:54:40

标签: c# powershell powershell-v3.0 powershell-v4.0 powershell-v5.0

在Powershell中有许多不同的方法来创建对象。我发布这个作为纯粹在Powerhell中创建对象的挑战。我正在寻找一种使用Add-Type创建对象来传递这些要求的方法:

  1. 强类型对象属性
  2. 实例化,使用:New-Object[My.Object]::New()[My.Object]@{'Property'='Value'}
  3. 自定义命名空间的一部分(即[My.Object])
  4. 可以进行类型检查。示例:$myVar -is [My.Object]
  5. 我知道可以在Visual Studio中创建可以实现此目的的dll,但我正在寻找一种纯粹的Powershell方法来创建对象。

    这是我最接近上述规则的例子:

    PS C:\> $memberDef = @"
    public String myString { get; set; }
    public int myInt { get; set; }
    "@
    
    PS C:\> Add-Type -Namespace "My.Namespace" -Name "Object" -MemberDefinition $memberDef
    
    PS C:\> $myObj = [My.Namespace.Object]@{'myString'='Foo'; 'myInt'=42}
    PS C:\> $myObj
    
    myString myInt
    -------- -----
    Foo         42
    

    话虽如此,还有其他(可能更好的)方法来创建外观,感觉和行为类似于本机Powershell对象的对象吗?

    不满足所有规则的示例

    弱类型对象属性:

    PS C:\> $myObj = "" | Select-Object -Property myString, myInt
    
    PS C:\> $myObj = New-Object -TypeName PSObject -Property @{'myString'='foo'; 'myInt'=42}
    
    
    PS C:\> $myObj = @{}; $myObj.myString = 'foo'; $myObj.myInt = 42
    
    PS C:\> $myObj.myInt = "This should result in an error."
    

    没有名称空间的对象:

    PS C:\> $typeDef = @"
    public class myObject {
       public string myString { get; set; }
       public int myInt { get; set; }
    }
    "@
    PS C:\> Add-Type -TypeDefinition $typeDef
    PS C:\> $myObj = [myObject]::new()
    
    PS C:\> $myObj = New-Object -TypeName PSObject -Property @{'myString'='foo'; 'myInt'=42}
    PS C:\> $myObj.PSObject.TypeNames.Insert(0, "myObject")
    

2 个答案:

答案 0 :(得分:1)

  
      
  1. 强类型对象
  2.   

你最接近的是一个明确输入的变量。这可以通过在赋值期间转换变量本身来实现:

PS C:\> [My.Namespace.Object]$myObj = [My.Namespace.Object]@{'myString'='Foo'; 'myInt'=42}
PS C:\> $myObj = 123
Cannot convert the "123" value of type "System.Int32" to type "My.Namespace.Object".
At line:1 char:1
+ $myObj = 123
+ ~~~~~~~~~~~~
    + CategoryInfo          : MetadataError: (:) [], ArgumentTransformationMetadataException
    + FullyQualifiedErrorId : RuntimeException

如您所见,这会导致$myObj仅接受可以隐式转换为该类型的新分配。

答案 1 :(得分:0)

这是我在Powershell中创建对象的最好方法,它是命名空间的一部分,涵盖了上述所有规则。

PS C:\> $memberDef = @"
public String myString { get; set; }
public int myInt { get; set; }
"@

PS C:\> Add-Type -Namespace "My.Namespace" -Name "Object" -MemberDefinition $memberDef

PS C:\> $myObj = [My.Namespace.Object]@{'myString'='Foo'; 'myInt'=42}
PS C:\> $myObj

myString myInt
-------- -----
Foo         42