Исходя из этого полезного вопроса/ответа: Цепочка конструкторов в PowerShell — вызов других конструкторов в том же классе.
Чтобы соответствовать способу вызова конструктора (например, [car]::new()
) и поскольку «ключевое слово hidden
» в любом случае не полностью скрывает метод, я рассматриваю возможность использования имени метода new()
(а не init()
для этого «вспомогательного» метода конструктора). на моих занятиях, например:
hidden new([string]$make) { $this.new($make, $null) }
Кажется, все работает нормально, но я почему-то боюсь, что при этом может возникнуть подвох.
Есть ли причина, по которой мне следует избегать имени «new
» для метода класса PowerShell?
@SantiagoSquarzon, спасибо за комментарий. Это означает, что если я попытаюсь обратиться к методу, вместо этого я просто получу конструктор (определенный системой), и именно так я и хочу, чтобы он реагировал.
Да, вам нужно будет использовать ненужное отражение, чтобы это работало [MyClass].GetMethod('new').Invoke($null, $this)
, и определения перегрузки будут показывать фактический метод вместо определений ctor. так что да, просто избегайте использования static new
и все будет хорошо
«Чтобы быть согласованным с тем, как вы вызываете конструктор» — почему вы пытаетесь обеспечить «согласованность» между двумя разными типами членов? Ваш метод инициализатора не является конструктором, не пытайтесь его замаскировать :)
Я также согласен с Матиасом, не стал бы использовать и рекомендовать new
в качестве названия метода. мое намерение состояло в том, чтобы просто ответить на возможные ограничения его использования
Кстати, я склоняюсь к противоположному направлению и предпочел бы hidden Initialize(...){}
- точно говорит вам, что он делает, мало места для двусмысленности :)
@MathiasR.Jessen, SantiagoSquarzon, спасибо, я ценю ваши ценные комментарии!
Есть ли причина, по которой мне следует избегать имени
new
для метода класса PowerShell?
Если исходить из строго технических соображений и оставить в стороне личные предпочтения/мнения, то, если метод является экземплярным методом, использование new
в качестве его имени не должно быть проблемой.
Как отмечалось в комментариях, возникла бы проблема, если бы метод был статическим, поскольку вы бы конфликтовали с новым внутренним членом .
Первой проблемой будет необходимость использовать отражение для вызова вашего метода в .ctor
:
class Test {
[string] $MyParam
Test() {
[Test].GetMethod('new').Invoke($null, $this)
}
Test([string] $myParam) {
$this.MyParam = $myParam
}
hidden static new([Test] $instance) {
$instance.MyParam = 'default value'
}
}
[Test]::new()
# MyParam
# -------
# default value
[Test]::new('other value')
# MyParam
# -------
# other value
Вторая проблема будет заключаться в том, что все определения перегрузок будут перепутаны, поскольку они будут показывать перегрузки вашего метода вместо реальных перегрузок конструктора:
[Test]::new
# OverloadDefinitions
# -------------------
# public static void new(Test instance);
Ожидаемое здесь будет (те же определения, как если бы вы делали [Test].GetConstructors()
):
[Test]::new
# OverloadDefinitions
# -------------------
# public Test();
# public Test(string myParam);
если бы вы попытались использовать
hidden static new([string]$make)
, возник бы конфликт, в противном случае все будет в порядке