¿Cómo se puede probar si un objeto tiene una propiedad específica?
Aprecio que puedo hacer ...
$members = Get-Member -InputObject $myobject
y luego a foreach
través del $members
, pero ¿hay una función para probar si el objeto tiene una propiedad específica?
Información adicional: El problema es que estoy importando dos tipos diferentes de archivos CSV, uno con dos columnas y el otro con tres. No pude hacer que el cheque funcionara con "Propiedad", solo con "NoteProperty" ... cualquiera que sea la diferencia
if ( ($member.MemberType -eq "NoteProperty" ) -and ($member.Name -eq $propertyName) )
powershell
powershell-3.0
SteveC
fuente
fuente
($object.property -ne $null)
?$null
valor?Respuestas:
¿Me gusta esto?
[bool]($myObject.PSobject.Properties.name -match "myPropertyNameToTest")
fuente
$myObject.PSobject.Properties.Name -contains "myPropertyNameToTest"
es mejor. No hay necesidad de preocuparse por la posible coincidencia de patrones, y tampoco necesitará convertir a booleano.ThisisMyProperty
y le gustaría verificarMyProperty
? Todas las soluciones en esta respuesta resultarán en un falso positivo.Puedes usar
Get-Member
if(Get-Member -inputobject $var -name "Property" -Membertype Properties){ #Property exists }
fuente
if($var | Get-Member Property){ }
incluso más corto pero menos legible:if($var | gm Property){ }
Esto es conciso y legible:
"MyProperty" -in $MyObject.PSobject.Properties.Name
Podemos ponerlo en una función:
function HasProperty($object, $propertyName) { $propertyName -in $object.PSobject.Properties.Name }
fuente
?.
equivalente): | Esto también fallará para ciertas variaciones de$MyObject
, notablemente $ null. Este no fue el caso con el encadenamiento nulo fuera del Modo Estricto.He estado usando lo siguiente que devuelve el valor de la propiedad, ya que se accedería a través de
$thing.$prop
, si la "propiedad" existiera y no arrojara una excepción aleatoria. Si la propiedad "no existe" (o tiene un valor nulo),$null
se devuelve: este enfoque funciona en / es útil para el modo estricto , porque, bueno, Gonna Catch 'em All.Encuentro este enfoque útil porque permite que los objetos personalizados de PS, los objetos .NET normales, las tablas hash de PS y las colecciones de .NET como Dictionary se traten como "equivalentes de tipo pato" , lo que considero que encaja bastante bien con PowerShell.
Por supuesto, esto no cumple con la definición estricta de "tiene una propiedad" ... a la que esta pregunta puede limitarse explícitamente. Si acepta la definición más amplia de "propiedad" asumida aquí, el método puede modificarse trivialmente para devolver un valor booleano.
Function Get-PropOrNull { param($thing, [string]$prop) Try { $thing.$prop } Catch { } }
Ejemplos:
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"
Y, este comportamiento podría no ser [siempre] deseable ... es decir. no es posible distinguir entre
x.Count
yx["Count"]
.fuente
MyProperty" -in $MyObject.PSobject.Properties.Name
Sin embargo, para mí no funcionó$MyObject.PSobject.Properties.Name.Contains("MyProperty")
trabajos
fuente
Si está utilizando StrictMode y el psobject puede estar vacío, le dará un error.
A todos los efectos, esto servirá:
if (($json.PSobject.Properties | Foreach {$_.Name}) -contains $variable)
fuente
Real similar a una verificación de javascript:
foreach($member in $members) { if($member.PropertyName) { Write $member.PropertyName } else { Write "Nope!" } }
fuente
use strict
.Solo para aclarar dado el siguiente objeto
$Object
Con las siguientes propiedades
type : message user : [email protected] text : ts : 11/21/2016 8:59:30 PM
Lo siguiente es cierto
$Object.text -eq $NULL $Object.NotPresent -eq $NULL -not $Object.text -not $Object.NotPresent
Entonces, las respuestas anteriores que verifican explícitamente la propiedad por nombre son la forma más correcta de verificar que esa propiedad no esté presente.
fuente
Simplemente verifique con nulo.
($myObject.MyProperty -ne $null)
Si no ha configurado PowerShell en StrictMode , esto funciona incluso si la propiedad no existe:
$obj = New-Object PSObject; Add-Member -InputObject $obj -MemberType NoteProperty -Name Foo -Value "Bar"; $obj.Foo; # Bar ($obj.MyProperty -ne $null); # False, no exception
fuente
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}
y obtendrá un error La propiedad 'StartDate' no se puede encontrar en este objeto. Sin embargo , necesito calificar mi comentario; no lo recibe si no se establece Strictmode. Siempre lo tengo configurado, ¡así que nunca me di cuenta hasta que probé esto! Aún así, creo que la mayoría de la gente usa (o debería usar) 'Set-Strictmode'.Terminé con la siguiente función ...
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; } }
fuente
Recientemente cambié para establecer la versión 2.0 en modo estricto y mis pruebas nulas fallaron.
Agregué una función:
#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 }
Ahora codifico
if (exists $run main) { ...
más bien que
if ($run.main -ne $null) { ...
y estamos en camino. Parece funcionar en objetos y tablas hash
Como beneficio no deseado, es menos mecanografiado.
fuente
Solo quería agregar algo a la discusión, porque pasé horas depurando un código que funcionaba en otro lugar.
Respuesta de CB. funciona bien para hacer coincidir la variable con los nombres de las propiedades (como cadenas). El problema comenzó cuando la variable coincidía con una parte del nombre de una propiedad.
if([bool]($allFiles.PSobject.Properties.name -match $_.Name) -ne $true){
Más tarde lo usé para referirme a la propiedad de un objeto, pero como solo coincidía con una parte de otra propiedad, por lo que no existía una propiedad real con ese nombre exacto, la operación devolvió el valor 'nulo'.
Solo más tarde utilicé la solución propuesta por dan-gph , que es muy ordenada:
if([bool]($_.Name -in $allFiles.PSobject.Properties.Name) -ne $true){
Esto aseguró que los dos valores fueran idénticos . Sabía dónde buscar, pero aún así fue doloroso incluso darme cuenta de que el problema es que varios nombres coinciden con cadenas de 2 caracteres. prefijo pero por lo demás igual.
fuente
Acabo de comenzar a usar PowerShell con PowerShell Core 6.0 (beta) y lo siguiente simplemente funciona:
if ($members.NoteProperty) { # NoteProperty exist }
o
if (-not $members.NoteProperty) { # NoteProperty does not exist }
fuente
Puede consultar con:
($Member.PropertyNames -contains "Name")
esto comprobará la propiedad nombradafuente
Para identificar cuál de los objetos de una matriz tiene una propiedad
$HasProperty = $ArrayOfObjects | Where-Object {$_.MyProperty}
fuente