Bir nesnenin belirli bir özelliğe sahip olup olmadığını nasıl test edebilirsiniz?


94

Bir nesnenin belirli bir özelliğe sahip olup olmadığını nasıl test edebilirsiniz?

Yapabildiğim için minnettarım ...

$members = Get-Member -InputObject $myobject 

ve sonra foreachiçinden $membersancak nesne belirli bir özelliği varsa teste için bir işlevi var mı?

Ek Bilgi: Sorun, biri iki sütunlu, diğeri üç sütunlu olmak üzere iki farklı türde CSV dosyasını içe aktarıyorum. Çeki "Mülk" ile çalışmak için alamadım, sadece "NoteProperty" ile ... fark ne olursa olsun

if ( ($member.MemberType -eq "NoteProperty" ) -and ($member.Name -eq $propertyName) ) 

6
($object.property -ne $null)?
arco444

2
Mülkiyetin var olup olmadığı ancak bir $nulldeğere sahip olup olmadığı önemli mi
Matta

1
@ arco444 hayır - başarılı olmak için mülkün var olmasını gerektirir. - Bazı satırların o özelliği bile belirtmediği dinamik verileriniz varsa (yani bir web isteğinden), bu kontrol başarısız olacaktır. :(
BrainSlugs83

Yanıtlar:


105

Bunun gibi?

 [bool]($myObject.PSobject.Properties.name -match "myPropertyNameToTest")

16
Bu yanıt yalnızca powerShell v3 veya üstü için çalışır. Aşağıdakiler, powerShell v2 ve üzeri ile bile çalışmalıdır: [bool] ($ file.psobject.Properties | burada {$ _. Name -eq "myPropertyNameToTest"})
Patrick

34
$myObject.PSobject.Properties.Name -contains "myPropertyNameToTest"daha iyi. Olası desen eşleştirme konusunda endişelenmenize gerek yok ve o zaman Boolean'a çevirmeniz de gerekmeyecek.
Bacon Bits

2
Ya nesnenin özelliği varsa ThisisMyPropertyve kontrol etmek isterseniz MyProperty? Bu yanıttaki tüm çözümler yanlış pozitifle sonuçlanacaktır.
Zoltán Tamási

3
@KolobCanyon Bu, Katı Modda çalışmayacaktır.
user2864740

1
Bu kod, örneğin "Sayım" için test yaparsanız ve nesnenin "ThingCount" adında bir özelliği varsa, yanlış bir pozitif verir.
dan-gph

72

Kullanabilirsiniz Get-Member

if(Get-Member -inputobject $var -name "Property" -Membertype Properties){
#Property exists
}

12
En iyi cevap IMHO. Bu, PSobject üyesi olmayan .NET nesneleriyle çalışır. Ayrıca, nesnenin hangi tür üye içerdiğiyle ilgilenmezsek, sadece üye adı ile -Membertype seçeneğini kaldırabiliriz. Invoke-RestMethod veya ConvertFrom-Json nesneleriyle çok kullanışlı!
Mister_Tom

2
Türü kontrol etmeden kısa sözdizimi:, if($var | Get-Member Property){ }daha da kısa ama daha az okunabilir:if($var | gm Property){ }
zett42

Bu bence en iyi cevap.
Kiran hegde

25

Bu kısa ve öz ve okunaklı:

"MyProperty" -in $MyObject.PSobject.Properties.Name

Bunu bir fonksiyona koyabiliriz:

function HasProperty($object, $propertyName)
{
    $propertyName -in $object.PSobject.Properties.Name
}

Bu cevabı seviyorum, ancak CB'nin cevabının yaptığı bazı durumlarda işe yaramıyor gibi görünüyor.
edwin

Veya, "kısa ve öz" = "İyi bir geri dönüş kullanım durumu olmadan Katı Mod aracılığıyla gereksiz önemsiz yere girildiğinde" (yani, ?.eşdeğeri yok ): | Bu aynı zamanda belirli varyasyonlarda $MyObject, özellikle $ null için başarısız olacaktır . Katı Mod dışında sıfır zincirleme ile durum böyle değildi.
user2864740

5

"Özellik" var olacaksa ve rastgele bir istisna oluşturmayacaksa, aracılığıyla erişilebileceği gibi özellik değerini döndüren$thing.$prop aşağıdakileri kullanıyorum . Eğer özelliği "yoksa" (veya boş bir değere sahipse) $nulldöndürülür: bu yaklaşım katı modda çalışır / yararlıdır , çünkü hepsini Yakalayacağım.

Bu yaklaşımı kullanışlı buluyorum çünkü PS Özel Nesneleri, normal .NET nesneleri, PS HashTable'lar ve Dictionary gibi .NET koleksiyonlarının PowerShell için oldukça uygun olduğunu düşündüğüm "ördek tipi eşdeğer" olarak değerlendirilmesine izin veriyor.

Elbette bu, "bir özelliğe sahiptir" ifadesinin katı tanımına uymuyor .. ki bu soru açıkça bununla sınırlı olabilir. Burada varsayılan "özellik" kavramının daha büyük tanımını kabul ederseniz, yöntem bir boole döndürmek için önemsiz bir şekilde değiştirilebilir.

Function Get-PropOrNull {
    param($thing, [string]$prop)
    Try {
        $thing.$prop
    } Catch {
    }
}

Örnekler:

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"

Ve bu davranış [her zaman] istenmeyebilir .. yani. x.Countve arasında ayrım yapmak mümkün değildir x["Count"].


Bir özellik veya almak için $nullekstra fonksiyonu olmadan: $x = try{ $someObject.someProp } catch{ $null }. Sen atlayabilirsiniz $nullgelen catchbloğun ama IMO okunabilirliği arttırmak.
zett42

3

Benim MyProperty" -in $MyObject.PSobject.Properties.Nameiçin işe yaramadı

$MyObject.PSobject.Properties.Name.Contains("MyProperty")

İşler


2

StrictMode kullanıyorsanız ve psobject boş olabilirse, size bir hata verecektir.

Tüm amaçlar için bu şunları yapacaktır:

    if (($json.PSobject.Properties | Foreach {$_.Name}) -contains $variable)

1

JavaScript kontrolüne çok benzer:

foreach($member in $members)
{
    if($member.PropertyName)
    {
        Write $member.PropertyName
    }
    else
    {
        Write "Nope!"
    }
}

1
Özellik gerçekte $ null değerine sahipse bu işe yaramayabilir.
Tola Odejayi

8
PowerShell katı moddaysa bu başarısız olur.
Ian Kemp

@IanKemp Katı mod nedir? Yürütme Politikasını beğendiniz mi?
Kolob Canyon

1
@KolobCanyon docs.microsoft.com/en-za/powershell/module/… - aslında JavaScript'in PS eşdeğeridir use strict.
Ian Kemp

1
Bu, özellik varsa ve $ false olarak ayarlanmışsa da çalışmaz.

1

Sadece aşağıdaki nesneyi açıklığa kavuşturmak için

$Object

Aşağıdaki özelliklerle

type        : message
user        : john.doe@company.com
text        : 
ts          : 11/21/2016 8:59:30 PM

Aşağıdakiler doğrudur

$Object.text -eq $NULL
$Object.NotPresent -eq $NULL

-not $Object.text
-not $Object.NotPresent

Bu nedenle, mülkü adıyla açıkça kontrol eden önceki yanıtlar, mülkün mevcut olmadığını doğrulamanın en doğru yoludur.


1

Sadece null'a karşı kontrol edin.

($myObject.MyProperty -ne $null)

Eğer yoksa StrictMode için PowerShell set özelliği yok bile, bu çalışır:

$obj = New-Object PSObject;                                                   
Add-Member -InputObject $obj -MemberType NoteProperty -Name Foo -Value "Bar";
$obj.Foo; # Bar                                                                  
($obj.MyProperty -ne $null);  # False, no exception

2
Görebildiğim kadarıyla, bu özellik varsa ve $ null ise çalışıyor, ancak özellik yoksa değil - boş kontrol yapmak için ona erişmeye çalışmak bir istisna atıyor.
Peter

@Peter Özellik mevcut olmadığında bir istisna atan boş kontrolün bir örneğini sağlayabilir misiniz? Bir mülkün olmadığı ve istisnasının olmadığı bir örnek ekledim.
Shaun Luttin

2
Bunu çalıştırın: 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}ve bir hata alırsınız 'StartDate' özelliği bu nesnede bulunamaz. Ancak yorumumu nitelendirmem gerekiyor - Katı mod ayarlanmamışsa anlamazsınız. Her zaman ayarladım, bu yüzden bunun için test edene kadar asla fark etmedim! Yine de, çoğu insanın 'Set-Strictmode' kullandığını (veya kullanması gerektiğini) düşünüyorum.
Peter

2
Muhtemelen en iyisi cevabınızı değerlendirirseniz, olumsuz oyumu kaldırırım. Herkes bir şeyler öğrendi, mesele bu :-)
Peter

0

Aşağıdaki işlevi elde ettim ...

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; 
    }
}

0

Yakın zamanda sıkı mod sürüm 2.0'a geçtim ve sıfır testlerim başarısız oldu.

Bir işlev ekledim:

#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
}

Şimdi kodluyorum

if (exists $run main) { ...

ziyade

if ($run.main -ne $null) { ...

ve yoldayız. Nesneler ve hashtable'lar üzerinde çalışıyor gibi görünüyor

İstenmeyen bir fayda olarak daha az yazı yazmaktır.


Null veya boş için her zaman şunu kullandım: IF ([string] :: IsNullOrEmpty ($ userID)) {write-host "Null or empty"}

0

Sadece tartışmaya eklemek istedim çünkü başka bir yerde çalışan bir kodda hata ayıklamak için saatler harcadım.

CB'nin cevabı . değişkeni özelliklerin isimleriyle (dizeler olarak) eşleştirmek için iyi çalışır. Değişken , bir özellik adının bir kısmıyla eşleştiğinde sorun başladı .

if([bool]($allFiles.PSobject.Properties.name -match $_.Name) -ne $true){

Daha sonra bunu bir nesnenin özelliğine başvurmak için kullandım, ancak başka bir özelliğin yalnızca bir parçasıyla eşleştiğinden, bu tam ada sahip gerçek bir özellik olmadığı için işlem 'null' değerini döndürdü.

Ancak daha sonra dan-gph tarafından önerilen çözümü kullandım , bu çok düzgün:

if([bool]($_.Name -in $allFiles.PSobject.Properties.Name) -ne $true){

Bu, iki değerin aynı olmasını sağladı . Nereye bakacağımı biliyordum ama yine de sorunun 2 karakterli dizelerle eşleşen birkaç isim olduğunu anlamak acı vericiydi. önek, ancak aksi halde aynı.


-1

PowerShell'i PowerShell Core 6.0 (beta) ile kullanmaya başladım ve aşağıdakiler basitçe çalışıyor:

if ($members.NoteProperty) {
   # NoteProperty exist
}

veya

if (-not $members.NoteProperty) {
   # NoteProperty does not exist
}

1
Sıkı mod açıkken değil
Casper Leon Nielsen

-1

Şunlarla kontrol edebilirsiniz:

($Member.PropertyNames -contains "Name") bu, Adlandırılmış özelliği kontrol edecektir


-1

Bir dizideki nesnelerin hangisinin bir özelliğe sahip olduğunu belirlemek için

$HasProperty = $ArrayOfObjects | Where-Object {$_.MyProperty}

Özellik mevcut olmadığında StrictMode'da başarısız olur.
user2864740
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.