PowerShell 类

3

我曾在 Powershell 中使用闭包来创建具有静态和实例方法的类,是否有更好的方法?

创建一个带有静态 "方法" 的对象。

function person_get_type {
    return 'Person'
}

function make_person {
    param
    (
    [parameter(mandatory=$true)][string]$name)

    $properties = @{'name'=$name;'get_type'=$null}
    $person = New-Object –TypeName PSObject –Prop $properties
    $person.get_type = ${function:person_get_type}
    return $person
}

$person = make_person -name 'James'
$type = $person.get_type.InvokeReturnAsIs()
Write-Host $type

创建一个带有实例“方法”的对象。
function dog_get_type {
    return 'Dog'
}

function dog_make_get_name{
      param 
      (
      [Parameter(Mandatory=$true)][System.Management.Automation.PSObject]$self
      )
      return  {return $self.name}.GetNewClosure()
}

function dog_make_set_name{
      param 
      (
      [Parameter(Mandatory=$true)][System.Management.Automation.PSObject]$self
      )
      return  {param([parameter(mandatory=$true)][string]$name) $self.name = $name}.GetNewClosure()
}

function make_dog {
    param
    (
    [parameter(mandatory=$true)][string]$name
    )

    $properties = @{'name'=$name;'get_type'=$null;'get_name'=$null;'set_name'=$null}
    $dog = New-Object –TypeName PSObject –Prop $properties
    $dog.get_type = ${function:dog_get_type}
    $dog.get_name = dog_make_get_name -self $dog
    $dog.set_name = dog_make_set_name -self $dog
    return $dog
}

$dog = make_dog -name 'Spot'
$name = $dog.get_name.InvokeReturnAsIs()
Write-Host $name

$dog.set_name.Invoke("Paws")
$name = $dog.get_name.InvokeReturnAsIs()
Write-Host $name

$stuff = @($person,$dog)
foreach($thing in $stuff) {
    Write-Host $thing.get_type.InvokeReturnAsIs()
}

我知道可以使用以下方法:

$object = New-Module -AsCustomObject -ScriptBlock {...}

但我认为使用这种方法无法创建实例方法。

你也可以将ScriptMethod成员添加到对象中。 - mjolinor
相关链接:https://dev59.com/u2Ml5IYBdhLWcg3wFThP - Anthony Neace
来自未来的读者:截至Powershell 5.0,类已成为语言的一级组成部分。不再需要任何修补程序。https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_classes?view=powershell-5.1 - TurtleZero
1个回答

4

使用New-Module可以轻松创建实例方法。 你的实例字段是脚本块中的顶级变量,例如:

$sb = {
    param($theName,$theAge,$theBreed)

    $Name = $theName
    $Age = $theAge
    $Breed = $theBreed

    $global:NumDogs++

    function Description {
        "Dog named $Name, age $Age, breed $Breed"
    }

    function get_NumDogs {
        "Total number of dogs is $NumDogs"
    }
    Export-ModuleMember -Variable Name,Age,Breed -Function Description,get_NumDogs
}


$dog1 = New-Module $sb -AsCustomObject -ArgumentList 'Mr. Bill',1,'Jack Russell'
$dog1.Name
$dog1.Age
$dog1.Description()
$dog1.get_NumDogs()
$dog2 = New-Module $sb -AsCustomObject -ArgumentList Fluffy,3,Poodle
$dog2.Name
$dog2.Age
$dog2.Description()
$dog2.get_NumDogs()

谢谢。这就是我在寻找的东西。 - Matthew S
这似乎可以工作,直到尝试使用setter方法更改例如$Name。我猜是因为$Name是方法本地变量?如何通过方法更新“实例范围”内的变量? - Adrian Frühwirth

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接