简体   繁体   English

定义自定义Powershell对象

[英]Defining Custom Powershell Objects

There are many different ways to create objects in Powershell. 在Powershell中有许多不同的方法来创建对象。 I am posting this as a challenge to create objects purely in Powerhell. 我发布这个作为纯粹在Powerhell中创建对象的挑战。 I am looking for a way to create objects using Add-Type that pass these requirements: 我正在寻找一种使用Add-Type创建对象来传递这些要求的方法:

  1. Strongly-Typed object properties 强类型对象属性
  2. Instantiated, using: New-Object , [My.Object]::New() , [My.Object]@{'Property'='Value'} 实例化,使用: New-Object[My.Object]::New()[My.Object]@{'Property'='Value'}
  3. Part of a custom Namespace (ie [My.Object]) 自定义命名空间的一部分(即[My.Object])
  4. Can be type-checked. 可以进行型式检查。 Example: $myVar -is [My.Object] 示例: $myVar -is [My.Object]

I know dll's can be created in Visual Studio that would accomplish this, but I am looking for a purely Powershell way to create objects. 我知道可以在Visual Studio中创建可以实现此目的的dll,但我正在寻找一种纯粹的Powershell方法来创建对象。

Here is the closest example I have that satisfy the rules above: 以下是我最接近上述规则的示例:

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

With that said, are there other (Possibly better) ways to create objects that look, feel, and act like native Powershell objects? 话虽如此,是否有其他(可能更好)的方法来创建外观,感觉和行为像本机Powershell对象的对象?

Examples that do not satisfy all rules 不满足所有规则的示例

Weakly-Typed object properties: 弱类型对象属性:

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."

Objects without namespaces: 没有命名空间的对象:

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")
  1. Strongly-Typed object 强类型对象

The closest you're gonna get is an explicitly typed variable. 你最接近的是一个明确的类型变量。 This can be accomplished by casting the variable itself during assignment: 这可以通过在赋值期间自己转换变量来完成:

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

As you can see, this causes $myObj to only accept new assignments that can be implicitly converted to the type. 如您所见,这会导致$myObj仅接受可以隐式转换为该类型的新分配。

This is the best way I have found to create an object in Powershell that is part of a namespace and covers all the rules above. 这是我在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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM