Як можна перевірити, чи має об’єкт певну властивість?


93

Як можна перевірити, чи має об’єкт певну властивість?

Ціную, що я можу зробити ...

$members = Get-Member -InputObject $myobject 

а потім foreachчерез $members, але чи існує функція для перевірки, чи має об’єкт певну властивість?

Додаткова інформація: Проблема полягає в тому, що я імпортую два різні типи файлів CSV, один із двох стовпців, інший із трьома. Я не зміг змусити чек працювати з "Властивістю", лише з "Приміткою власності" ... незалежно від різниці

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

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

2
Чи має значення, чи маєток справді існує, але має $nullзначення
Мт

1
@ arco444 nope - для досягнення успіху потрібне існування властивості. - Якщо у вас є динамічні дані (тобто з веб-запиту), де деякі рядки навіть не вказують цю властивість, ця перевірка не вдасться. :(
BrainSlugs83

Відповіді:


103

Подобається це?

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

16
Ця відповідь працює лише для powerShell v3 або новішої версії. Наступне повинно працювати навіть із PowerShell v2 і вище: [bool] ($ file.psobject.Properties | де {$ _. Name -eq "myPropertyNameToTest"})
Патрік

33
$myObject.PSobject.Properties.Name -contains "myPropertyNameToTest"краще. Не потрібно турбуватися про можливе збіг зразків, і тоді вам також не потрібно буде перетворюватись на Boolean.
Bacon Bits

2
Що робити, якщо об’єкт має властивість, ThisisMyPropertyі ви хочете перевірити наявність MyProperty? Усі рішення у цій відповіді призведуть до помилково позитивного.
Zoltán Tamási

3
@KolobCanyon Це не працюватиме в суворому режимі.
user2864740

1
Цей код дасть помилково позитивний результат, якщо, наприклад, ви тестуєте на "Count" і об'єкт має властивість під назвою "ThingCount".
dan-gph

71

Можна використовувати Get-Member

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

12
Краща відповідь IMHO. Це працює з об'єктами .NET, які не мають члена PSobject. Ми також можемо видалити параметр -Membertype, якщо нам байдуже, який тип елемента містить об'єкт - лише ім'я члена. Дуже корисно з об’єктами Invoke-RestMethod або ConvertFrom-Json!
Mister_Tom

2
Короткий синтаксис без перевірки типу:, if($var | Get-Member Property){ }навіть коротший, але менш читабельний:if($var | gm Property){ }
zett42

Це, на мій погляд, найкраща відповідь.
Кіран Хегде,

25

Це стисло і читається:

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

Ми можемо поставити це у функцію:

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

Мені подобається ця відповідь, але, здається, вона не працює в деяких випадках, коли відповідь ЦБ працює.
Edwin

Або, де "лаконічний" = "непотрібне сміття, введене через суворий режим без належного резервного випадку використання" (тобто без ?.еквівалента): | Це також не вдасться для певних варіацій $MyObject, зокрема $ null. Такого не було у випадку з нульовим ланцюгом поза строгим режимом.
користувач2864740

5

Я використовував наступне, що повертає значення властивості, оскільки воно буде доступне через$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"].


3

Однак для мене MyProperty" -in $MyObject.PSobject.Properties.Nameце не спрацювало

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

робіт


2

Якщо ви використовуєте StrictMode, і psobject може бути порожнім, це видасть вам помилку.

Для всіх цілей це буде робити:

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

1

Реальне схоже на перевірку javascript:

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

1
Це може не спрацювати, якщо властивість насправді має значення $ null.
Тола Одеджаї,

8
Це не вдасться, якщо PowerShell знаходиться в суворому режимі.
Ян Кемп,

@IanKemp Що таке строгий режим? Як політика виконання?
Каньйон Колоба

1
@KolobCanyon docs.microsoft.com/en-za/powershell/module/… - по суті, це PS, еквівалентний JavaScript use strict.
Ian Kemp

1
Це також не буде працювати, якщо властивість існує, і встановлено значення $ false.

1

Тільки для уточнення з огляду на наступний об’єкт

$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

Тож попередні відповіді, які явно перевіряють властивість за назвою, є найбільш правильним способом перевірити відсутність цієї властивості.


1

Просто перевірте, чи не має значення null.

($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

2
Наскільки я бачу, це працює, якщо властивість існує і має значення $ null, але не якщо властивість не існує - спроба отримати до нього доступ для перевірки нуля видає виняток.
Пітер,

@Peter Чи можете ви навести приклад перевірки на нуль, що видає виняток, коли властивість не існує. Я додав приклад, коли властивість не існує, і немає винятків.
Шон Луттін,

2
Запустіть це: 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' не може бути знайдена на цьому об'єкті. Однак мені потрібно кваліфікувати мій коментар - ви не отримаєте його, якщо не встановлено строгий режим. У мене це завжди встановлено, тому ніколи не усвідомлював, поки не перевірив це! Тим не менше, я думаю, що більшість людей використовують (або повинні використовувати) 'Set-Strictmode'.
Пітер

2
Напевно, найкраще, якщо ви кваліфікуєте свою відповідь, і я скасую свій голос проти? Кожен чомусь навчився, в чому суть :-)
Пітер,

0

Я отримав наступну функцію ...

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

Нещодавно я перейшов на встановлення строгого режиму -версія 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) { ...

і ми вже в дорозі. Здається, працює над об’єктами та хештегами

Як ненавмисна вигода, це менше набору тексту.


Для нуля чи порожнього я завжди використовував: IF ([рядок] :: IsNullOrEmpty ($ userID)) {хост запису "Нуль або порожній"}

-1

Я щойно почав використовувати PowerShell з PowerShell Core 6.0 (бета-версія), а наступне просто працює:

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

або

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

1
Не зі строгим режимом
Каспер Леон Нільсен

-1

Ви можете проконсультуватися з:

($Member.PropertyNames -contains "Name") це перевірить наявність властивості Named


-1

Для визначення того, які з об’єктів масиву мають властивість

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

Помилка в StrictMode, коли властивість не існує.
користувач2864740
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.