12

可能这个问题之前已经回答过......但我还没有找到满足我需求的具体答案。

顺便说一句,我正在使用 PowerShell 3

好吧,我是 PowerShell 的新手,但我作为 C# 开发人员拥有丰富的经验,因此使用对象对我来说非常重要。

所以我想知道是否有一种干净的方法可以在 PowerShell 脚本中应用OOP 概念(不是所有的概念,尽管那会很棒),例如我想做一些特定的事情。

注意:我知道我可以在 PowerShell 中编写 C# 代码来创建 DTO,并且我可以在 C# 中创建 PowerShell 二进制模块,我过去做过,但我现在正在寻找的是编写的能力我在 PowerShell 中的所有代码,但以面向对象的方式

我想做的事情:

  • 在 PowerShell 中创建一个对象,并公开一个用 PowerShell 编写的函数,如下所示:

    function New-Person
    (
        [Parameter()][string]$firstName
    )
    {
        function Walk()
        {
            Write-Host "Walking...";
        }
    
        $person = New-Object psobject;
    
        $person | Add-Member -MemberType NoteProperty -Name FirstName -Value $firstName;
    
        #This line does not work
        #$person | Add-Member -MemberType CodeMethod -Name Walk -Value Walk;
    
        return $person;
    }
    
    $MyPerson = New-Person -firstName "JP";
    
    $MyPerson;
    
    #This line does not work
    $MyPerson.Walk();
    
  • 封装行为,这意味着在我的对象中创建函数,然后将它们标记为私有

  • [很高兴有]。创建基类,以便我可以继承和专门化我的行为覆盖方法

  • [很高兴有]。创建接口,以便我可以开始独立思考我的 PowerShell 方法的单元测试(我知道有像 Pester 这样的工具可以做到这一点,我只专注于 OOP 功能)

到目前为止我所做的是创建仅具有属性的对象(DTO),但我想为我的对象添加行为

如果你们指出我正确的方向,我将不胜感激

4

3 回答 3

13

使用方法创建对象的两个选项:

  1. 添加成员
  2. 新模块-AsCustomObject

代码示例:

$person | Add-Member -MemberType ScriptMethod -Value {
    'I do stuff!'
}

$person = New-Module -AsCustomObject -ScriptBlock {
    $Property = 'value'
    [string]$Other = 'Can be strongly typed'

    function MyMethod {
        'I do stuff!'
    }

}

编辑:谈到私人/公共......在后一个示例中,属性不会“默认”显示。您可以决定什么是公开的,Export-ModuleMember并指定将公开的-Variable(属性)和/或-Function(方法)。如果没有显式Export-ModuleMember,它将与“普通”模块中的行为相同 - 仅导出函数(方法)。

于 2013-02-12T15:37:14.343 回答
7

PowerShell v5 引入了完整的类支持,使您可以轻松地使用属性构建您自己的类并实现方法。

在此处查看 Trevor 关于该主题的精彩博文。Trevor Sullivan,实现一个 .net 类

独立示例

这是一个名为 Fox 的组合类型的 PowerShell 类,它有一个.Deploy()方法,应该显示这是如何完成的

class Fox {
    # describes the sixe of the fox
    [String] $Size;
    # Property: the foxes color
    [String] $Color;

    # Constructor: Creates a new Fox object, with the specified
    #              size and name / owner.
    Fox([string] $NewSize, [String] $NewName) {
        # describes the sixe of the fox
        $this.Size = $NewSize;
        # Property: the foxes color
        $this.Color = $NewName;
    }

    # Method: Change the size of the fox     
    [void] Morph([UInt32] $Amount) {
        try {
            $this.Size = $this.Size - $Amount;
        }
        catch {
            Write-Warning -Message 'You tried to set an invalid size!';
        }
    }

    # Method: BreakGlass resets the beer size to 0.
    [void] Deploy() {
        Write-Warning -Message "The $($this.Color) fox, which is $($this.Size) in stature, goes off into the distance"        
    }
}

在实践中: 在此处输入图像描述

于 2015-01-07T14:00:50.780 回答
4

如果你想要完整的 OOP(包括继承,虽然不是接口),那么PSClass是一个 MS-PL 许可的实现。

于 2013-02-13T12:12:01.030 回答