PowerShell 中的构造函数链 - 在同一 class 中调用其他构造函数
Constructor chaining in PowerShell - call other constructors in the same class
我在做一些测试时偶然发现了以下内容:
您可以根据需要重载 PoShv5 中的方法。如果你调用不带参数的方法,它可以在内部调用带参数的方法,让你的代码不冗余。我希望这对构造函数也是如此。
在此示例中,最后一个构造函数按预期工作。其他构造函数只有 return 个没有设置值的对象。
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
有办法解决这个问题吗?我错过了什么吗?
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#
- 我完全可以理解:-)
您只需在每个构造函数定义中重新实现成员分配。
补充:
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自身遵守的约定(比如输出时省略此类成员);但是,以这种方式标记的成员技术上仍然可以访问。
虽然不能直接调用 class 的构造函数,但可以使用 base-class 构造函数,使用类似 C# 的语法。
我在做一些测试时偶然发现了以下内容:
您可以根据需要重载 PoShv5 中的方法。如果你调用不带参数的方法,它可以在内部调用带参数的方法,让你的代码不冗余。我希望这对构造函数也是如此。
在此示例中,最后一个构造函数按预期工作。其他构造函数只有 return 个没有设置值的对象。
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
有办法解决这个问题吗?我错过了什么吗?
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#
- 我完全可以理解:-)
您只需在每个构造函数定义中重新实现成员分配。
补充
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自身遵守的约定(比如输出时省略此类成员);但是,以这种方式标记的成员技术上仍然可以访问。虽然不能直接调用 class 的构造函数,但可以使用 base-class 构造函数,使用类似 C# 的语法。