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

res*_*987 10 powershell constructor overloading class constructor-chaining

我正在做一些测试,偶然发现了以下情况:

您可以根据需要重载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
Run Code Online (Sandbox Code Playgroud)

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

mkl*_*nt0 16

为了补充Mathias R. Jessen的有用答案:

建议的方法使用隐藏的辅助方法,以弥补缺乏构造函数链中:

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
Run Code Online (Sandbox Code Playgroud)

这会产生:

Make    Model  Year
----    -----  ----
Generic        2017
Fiat           2017
Nissan  Altima 2015
Run Code Online (Sandbox Code Playgroud)

注意:

  • hidden关键字是多个的惯例的是PowerShell的本身观察(如省略输出当这样的成员); 但是,以这种方式标记的成员在技术上仍然可以访问.

  • 虽然你不能调用的构造相同的直接类,可以用这样做基类的构造函数,使用C#语法样.

  • 非常好的DRY-ish替代品,+ 1 (3认同)

Mat*_*sen 8

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Car() : $this("Porsche") {}
Car([string]$Make) {}
Run Code Online (Sandbox Code Playgroud)

没有解析器因为你错过了构造函数的主体定义而呕吐,我不希望很快就会看到它 - PowerShell团队表达了一种明确的愿望,即不要成为新的淡化的维护者C#- 我完全可以理解:-)

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