C# 如何在PowerShell中创建具有行为(方法)的真实对象?

C# 如何在PowerShell中创建具有行为(方法)的真实对象?,c#,powershell,powershell-2.0,powershell-3.0,C#,Powershell,Powershell 2.0,Powershell 3.0,也许这个问题以前已经得到了回答。。。。但我还没有找到一个具体的答案来满足我的需求 顺便说一句,我正在使用PowerShell 3 嗯,我是PowerShell的新手,但作为一名C#开发人员,我有很多经验,因此使用对象对我来说非常重要 因此,我想知道是否有一种干净的方法可以在PowerShell脚本中应用OOP概念(当然不是所有的,尽管那会很棒),例如,我想做一些特定的事情 注意:我知道我可以在PowerShell中编写C#代码来创建DTO,也可以在C#中创建PowerShell二进制模块,我过去

也许这个问题以前已经得到了回答。。。。但我还没有找到一个具体的答案来满足我的需求

顺便说一句,我正在使用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),但我想向对象添加行为


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

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

  • 添加成员
  • 新模块-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!'
        }
    
    }
    

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

    如果需要完整的OOP(包括继承,但不包括接口),则是MS-PL许可的实现

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

    看看特雷弗关于这个话题的博文

    独立示例 下面是一个称为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"        
        }
    }
    
    在实践中:

    这两个例子都很有效。我想用第一个。是否有任何方法可以在
    ScriptMethod
    -
    Value
    正文中请求参数?能够做一些事情,比如
    $MyPerson.Walk(“mioles或whateva的数量”)在函数定义中添加一个常规
    param
    块。e、 g.
    $obj=“foo”| Add Member-MemberType ScriptMethod-Value{param($first,$second)”第一个是$first,第二个是$second”}-Name DoStuff-PassThru$obj.DoStuff('abc','123')
    我假设我们从
    $person=newobject-TypeName PSObject开始,对吗?否则,
    addmember
    将提示
    为以下参数提供值:Name:
    。来自@latkin的代码按原样工作,就像这样。只是为了记录在案,我没有否决你的答案,我已经找到了那个项目,我正在做一些概念验证。投票给这个答案很好+谢谢你的链接,这正是我找不到的。