PowerShell 中的构造函数链接 - 调用同一类中的其他构造函数

Posted

技术标签:

【中文标题】PowerShell 中的构造函数链接 - 调用同一类中的其他构造函数【英文标题】:Constructor chaining in PowerShell - call other constructors in the same class 【发布时间】:2017-11-08 20:09:18 【问题描述】:

我正在做一些测试并偶然发现以下内容:

您可以根据需要重载 PoShv5 中的方法。如果你调用不带参数的方法,它可以在内部调用带参数的方法,以保持你的代码非冗余。我希望构造函数也是如此。

在此示例中,最后一个构造函数按预期工作。其他构造函数只返回没有设置值的对象。

Class car 
    [string]$make
    [string]$model
    [int]$Speed
    [int]$Year

    speedUp ()
        $this.speedUp(5)
    
    speedUp ([int]$velocity)
        $this.speed += $velocity
    

    # Constructor
    car () 
        [car]::new('mall', $Null, $null)
    

    car ([string]$make, [string]$model) 
        [car]::new($make, $model, 2017)
    

    car ([string]$make, [string]$model, [int]$Year)  
        $this.make = $make
        $this.model = $model
        $this.Year = $year
    


[car]::new() # returns "empty" car
[car]::new('Make', 'Nice model') # returns also an "empty" one
[car]::new( 'make', 'nice model', 2017) # returns a "filled" instance

有没有办法解决这个问题?我错过了什么吗?

【问题讨论】:

您正在寻找的称为构造函数链接,不,PowerShell 似乎没有任何语法:-|您只需要在每个构造函数定义中重新实现成员分配 【参考方案1】:

补充Mathias R. Jessen's helpful answer:

recommended approach 是使用隐藏的辅助方法来弥补构造函数链的不足

Class car 

    [string]$Make
    [string]$Model
    [int]$Year

    speedUp ()
        $this.speedUp(5)
    
    speedUp ([int]$velocity)
        $this.speed += $velocity
    

    # Hidden, chained helper methods that the constructors must call.
    hidden Init([string]$make)                  $this.Init($make, $null) 
    hidden Init([string]$make, [string]$model)  $this.Init($make, $model, 2017) 
    hidden Init([string]$make, [string]$model, [int] $year) 
        $this.make = $make
        $this.model = $model
        $this.Year = $year
    

    # Constructors
    car () 
        $this.Init('Generic')
    

    car ([string]$make) 
        $this.Init($make)
    

    car ([string]$make, [string]$model) 
        $this.Init($make, $model)
    

    car ([string]$make, [string]$model, [int]$year)  
        $this.Init($make, $model, $year)
    


[car]::new()                          # use defaults for all fields
[car]::new('Fiat')                    # use defaults for model and year
[car]::new( 'Nissan', 'Altima', 2015) # specify values for all fields

这会产生:

Make    Model  Year
----    -----  ----
Generic        2017
Fiat           2017
Nissan  Altima 2015

注意:

hidden 关键字更像是 PowerShell 本身遵守的约定(例如在输出时省略此类成员);但是,以这种方式标记的成员在技术上仍然可以访问。

虽然您不能直接调用 same 类的构造函数,但可以使用 base-class 构造函数,使用 C#-类似语法。

【讨论】:

非常好的 DRY-ish 替代品,+1【参考方案2】:

TL;DR:不!


您要查找的内容(重载的构造函数相互调用)也通俗地称为构造函数链接,在 C# 中大致如下所示:

class Car

    string Make;
    string Model;
    int Year;

    Car() : this("mall", null)
    
    

    Car(string make, string model) : this(make, model, 2017) 
    
    

    Car(string make, string model, int Year) 
     
        this.Make = make;
        this.Model = model;
        this.Year = year;
    

不幸的是,PowerShell 似乎没有任何语法 - 你不能这样做:

Car() : $this("Porsche") 
Car([string]$Make) 

没有因为缺少构造函数的主体定义而让解析器向您抛出,我不希望很快看到它 - PowerShell 团队已明确表示不想成为新的淡化的维护者C# - 我完全可以理解 :-)

您只需在每个构造函数定义中重新实现成员分配。

【讨论】:

以上是关于PowerShell 中的构造函数链接 - 调用同一类中的其他构造函数的主要内容,如果未能解决你的问题,请参考以下文章

静态构造函数, 静态成员初始化/调用顺序

虚函数和基类中的this指针的问题!

在powershell-ise中怎么调用powershell中的函数

C++中的复制构造函数

单击第二次链接PrimeFaces时,构造函数不会调用

Java学习笔记之十九super在Java继承中的用法小结