#powershell
#powershell
Вопрос:
У меня есть класс, в котором есть свойства для класса, но я хочу иметь возможность устанавливать их значения только внутри, но разрешать общедоступный метод доступа к нему. Поскольку в C нет эквивалента PS в классах, подобных этому#:
public string PropertyName {
get;
private set;
}
Я рассмотрел реализацию следующего обходного пути в своем классе, чтобы «частные» члены оставались скрытыми с помощью общедоступного средства доступа к свойству:
class MyClass {
hidden [string]$_PropertyName
MyClass( $propertyValue ) {
$this._PropertyName = $PropertyValue
$this | Add-Member -ScriptProperty -Name 'PropertyName' -Value {
return $this.$_PropertyName
} -SecondValue {
throw "Cannot write value to a readonly property"
}
}
}
Это хорошо работает и делает то, что я хочу, но у этого класса также есть пара статических свойств, для которых я хочу сделать то же самое из его статического конструктора. Хотя приведенный выше код работает для установки свойства для самого типа класса (заменяющего [MyClass]
$this
), существует небольшая особенность, которая делает синтаксис для доступа к свойству «только для чтения» несовместимым с обычным доступом к статическим членам:
hidden static [string]$_StaticProperty = 'someValue'
static MyClass() {
[MyClass] | Add-Member -ScriptProperty StaticProperty -Value {
return [MyClass]::$_StaticProperty
}
}
Я могу получить доступ StaticProperty
, но только так, как если бы это был элемент экземпляра:
[MyClass]::StaticProperty # ==> $null
[MyClass].StaticProperty # ==> someValue
Есть ли способ добавить статический элемент к типу, используя Add-Member
, чтобы я мог поддерживать согласованный синтаксис средства доступа?
Ответ №1:
Есть ли способ добавить статический элемент к типу с помощью Add-Member, чтобы я мог поддерживать согласованный синтаксис средства доступа?
НЕТ
Add-Member
был разработан, чтобы позволить пользователю добавлять синтетические свойства ETS к объектам экземпляра — задолго до того, как кто-либо задумался о добавлении class
ключевого слова в грамматику языка.
Другими словами, «статические члены» имеют нулевое значение в контексте ETS, поскольку члены ETS привязаны к идентификатору уже созданных объектов.
Если вы хотите, чтобы поведение члена класса соответствовало C #, используйте C#:
Add-Type @'
public class MyClass
{
static MyClass()
{
MyClass.StaticProperty = "some value";
}
public static string StaticProperty { get; private set; }
}
'@
# Use [MyClass]::StaticProperty
Комментарии:
1. Спасибо за ответ. Я пытался использовать классы PowerShell для некоторых вещей вместо
PSCustomObjects
того, чтобы использовать правильные классы, которые имеют смысл для некоторой работы, которую я выполняю, но обескураживает то, насколько ограничены классы PS, когда другие языки .NET содержат полный набор функций. Начинаю думать, что я должен просто начать писать классы на C #, поскольку классы PS в основном просто хотят определятьstructs
на практике.2. @BendertheGreatest Не уверен
struct
, что здесь правильная аналогия (классы PowerShell являются истинными ссылочными типами), но большой вопрос в том, чего вы пытаетесь достичь ? Пример в вашем вопросе довольно общий, но я подозреваю, что вы могли бы заменить переменную, доступную только для чтения в области модуля, для статического свойства в реальной жизни3. Этот пример скорее пример практики с классами в PowerShell, чтобы уйти от компиляции кода C # с
Add-Type
помощью производственного кода, посмотреть, что можно и чего нельзя с ними делать. Свойство, доступное только для чтения, работает, если вам нужно задать значение только один раз, но не в том случае, если объект должен измениться позже. Метод работает, но тогда зачем вообще использовать свойства? Это также показывает, что вам нужно сделать, чтобы контролировать, что делает получатель / установщик в целом. Существует интерес к определению поведения getter / setter, поэтому я не думаю, что я не согласен с тем, что PS поддерживает это.