Как вы можете проверить, имеет ли объект определенное свойство?
Цените, что я могу ...
$members = Get-Member -InputObject $myobject
а затем foreach
через $members
, но есть ли функция для проверки наличия у объекта определенного свойства?
Дополнительная информация: проблема в том, что я импортирую CSV-файл двух разных типов: один с двумя столбцами, а другой - с тремя. Я не мог заставить чек работать с «Свойством», только с «NoteProperty» ... какая бы разница
if ( ($member.MemberType -eq "NoteProperty" ) -and ($member.Name -eq $propertyName) )
powershell
powershell-3.0
SteveC
источник
источник
($object.property -ne $null)
?$null
ценность?Ответы:
Как это?
[bool]($myObject.PSobject.Properties.name -match "myPropertyNameToTest")
источник
$myObject.PSobject.Properties.Name -contains "myPropertyNameToTest"
лучше. Не нужно беспокоиться о возможном сопоставлении с образцом, и вам также не нужно будет приводить к логическому типу.ThisisMyProperty
и вы хотите его проверитьMyProperty
? Все решения в этом ответе приведут к ложному срабатыванию.Ты можешь использовать
Get-Member
if(Get-Member -inputobject $var -name "Property" -Membertype Properties){ #Property exists }
источник
if($var | Get-Member Property){ }
даже короче, но менееif($var | gm Property){ }
Это сжато и доступно для чтения:
"MyProperty" -in $MyObject.PSobject.Properties.Name
Мы можем поместить это в функцию:
function HasProperty($object, $propertyName) { $propertyName -in $object.PSobject.Properties.Name }
источник
?.
Е. Без эквивалента): | Это также не удастся для некоторых вариантов$MyObject
, в частности $ null. Но этого не было с нулевой цепочкой вне строгого режима.Я использовал следующее, которое возвращает значение свойства, поскольку к нему можно получить доступ
$thing.$prop
, если «свойство» должно существовать, а не генерировать случайное исключение. Если свойство «не существует» (или имеет нулевое значение), то$null
возвращается: этот подход работает в / полезен для строгого режима , потому что, ну, Gonna Catch 'em All.Я считаю этот подход полезным, потому что он позволяет обрабатывать пользовательские объекты PS, обычные объекты .NET, PS HashTables и коллекции .NET, такие как Dictionary, как «утиный эквивалент» , который, как я считаю, довольно хорошо подходит для PowerShell.
Конечно, это не соответствует строгому определению термина «имеет свойство» ... которым этот вопрос может быть явно ограничен. Если принять более широкое определение «свойства», предложенное здесь, метод можно тривиально изменить, чтобы он возвращал логическое значение.
Function Get-PropOrNull { param($thing, [string]$prop) Try { $thing.$prop } Catch { } }
Примеры:
Get-PropOrNull (Get-Date) "Date" # => Monday, February 05, 2018 12:00:00 AM Get-PropOrNull (Get-Date) "flub" # => $null Get-PropOrNull (@{x="HashTable"}) "x" # => "HashTable" Get-PropOrNull ([PSCustomObject]@{x="Custom"}) "x" # => "Custom" $oldDict = New-Object "System.Collections.HashTable" $oldDict["x"] = "OldDict" Get-PropOrNull $d "x" # => "OldDict"
И такое поведение может не [всегда] быть желательным ... т.е. невозможно различить
x.Count
иx["Count"]
.источник
Однако для меня
MyProperty" -in $MyObject.PSobject.Properties.Name
не сработало$MyObject.PSobject.Properties.Name.Contains("MyProperty")
работает
источник
Если вы используете StrictMode и объект psobject может быть пустым, это выдаст вам ошибку.
Для всех целей это подойдет:
if (($json.PSobject.Properties | Foreach {$_.Name}) -contains $variable)
источник
Реально похоже на проверку javascript:
foreach($member in $members) { if($member.PropertyName) { Write $member.PropertyName } else { Write "Nope!" } }
источник
use strict
.Просто чтобы уточнить, учитывая следующий объект
$Object
Со следующими свойствами
type : message user : john.doe@company.com text : ts : 11/21/2016 8:59:30 PM
Следующее верно
$Object.text -eq $NULL $Object.NotPresent -eq $NULL -not $Object.text -not $Object.NotPresent
Таким образом, более ранние ответы, в которых явно проверяется свойство по имени, являются наиболее правильным способом проверить, что это свойство отсутствует.
источник
Просто проверьте против нуля.
($myObject.MyProperty -ne $null)
Если вы не установили PowerShell на StrictMode , это работает, даже если свойство не существует:
$obj = New-Object PSObject; Add-Member -InputObject $obj -MemberType NoteProperty -Name Foo -Value "Bar"; $obj.Foo; # Bar ($obj.MyProperty -ne $null); # False, no exception
источник
Set-Strictmode -version Latest;$obj = ConvertFrom-Json -InputObject '{"name":"test", "version":"1.1.0"}';If($obj.StartDate -ne $null){Write-Verbose -Message $obj.startDate -Verbose}
и вы получите сообщение об ошибке. Свойство StartDate не может быть найдено для этого объекта. Однако мне нужно уточнить свой комментарий - вы не получите его, если не установлен Strictmode. У меня он всегда был установлен, поэтому никогда не осознавал, пока не протестировал его! Тем не менее, я думаю, что большинство людей используют (или должны использовать) Set-Strictmode.У меня получилась следующая функция ...
function HasNoteProperty( [object]$testObject, [string]$propertyName ) { $members = Get-Member -InputObject $testObject if ($members -ne $null -and $members.count -gt 0) { foreach($member in $members) { if ( ($member.MemberType -eq "NoteProperty" ) -and ` ($member.Name -eq $propertyName) ) { return $true } } return $false } else { return $false; } }
источник
Недавно я переключился на установку strict-mode -version 2.0, и мои нулевые тесты не прошли.
Я добавил функцию:
#use in strict mode to validate property exists before using function exists { param($obj,$prop) try { if ($null -ne $obj[$prop]) {return $true} return $false } catch { return $false } return $false }
Теперь я кодирую
if (exists $run main) { ...
скорее, чем
if ($run.main -ne $null) { ...
и мы в пути. Кажется, работает с объектами и хэш-таблицами
В качестве непреднамеренного преимущества меньше набора текста.
источник
Я просто хотел добавить к обсуждению, потому что я просто часами отлаживал код, который работал где-то еще.
Ответ CB. хорошо работает для сопоставления переменной с именами свойств (в виде строк). Проблема началась, когда переменная совпала с частью имени свойства.
if([bool]($allFiles.PSobject.Properties.name -match $_.Name) -ne $true){
Позже я использовал его для ссылки на свойство объекта, но поскольку оно соответствовало только части другого свойства, поэтому фактического свойства с таким точным именем не существовало, операция вернула значение «null».
Только позже я использовал решение, предложенное dan-gph , оно очень аккуратное:
if([bool]($_.Name -in $allFiles.PSobject.Properties.Name) -ne $true){
Это обеспечивало идентичность двух значений . Я знал, где искать, но все же было больно даже понять, что проблема в нескольких строках, совпадающих с именами, с двумя символами. префикс, но в остальном то же самое.
источник
Я только начал использовать PowerShell с PowerShell Core 6.0 (бета), и следующее просто работает:
if ($members.NoteProperty) { # NoteProperty exist }
или
if (-not $members.NoteProperty) { # NoteProperty does not exist }
источник
Вы можете проверить:
($Member.PropertyNames -contains "Name")
это проверит свойство Namedисточник
Для определения того, какой из объектов в массиве имеет свойство
$HasProperty = $ArrayOfObjects | Where-Object {$_.MyProperty}
источник