如何测试对象是否具有特定的属性?

如何测试对象是否具有特定的属性?

感激我能做..。

$members = Get-Member -InputObject $myobject

然后 foreach通过 $members,但是是否有一个函数来测试对象是否具有特定的属性?

附加信息: 问题是我导入了两种不同类型的 CSV 文件,一种有两列,另一种有三列。我无法使用“ Property”来处理支票,只能使用“ NoteProperty”... < em > 不管有什么区别

if ( ($member.MemberType -eq "NoteProperty" ) -and ($member.Name -eq $propertyName) )
152550 次浏览

真正类似于 javascript 检查:

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

你可以使用 Get-Member

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

像这样吗?

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

我最终得到了以下函数..。

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

检查一下空。

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

澄清一下 考虑到以下事实

$Object

With the following properties

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

因此,前面的按名称显式检查属性的答案是验证该属性不存在的最正确方法。

如果您正在使用 StrictMode,并且 psoobject 可能为空,那么它将给您一个错误。

无论出于何种目的,这样做都可以:

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

我刚开始在 PowerShell Core 6.0(beta 版)中使用 PowerShell,下面的工作很简单:

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

or

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

我一直在使用下面的 返回属性值,因为它将通过 $thing.$prop访问,如果“属性”是存在的,而不是抛出一个随机异常。如果属性“不存在”(或者有一个空值) ,那么返回 $null: 这种方法在/中起作用,对于 严格模式来说很有用,因为,好吧,要全部抓住它们。

我发现这种方法很有用,因为 它允许 PS 自定义对象,正常。NET 对象、 PS HashTables 和。像 Dictionary 这样的 NET 集合被视为“ Duck 类型的等价物”非常适合 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"

And, this behavior might not [always] be desired.. ie. it's not possible to distinguish between x.Count and x["Count"].

这篇文章简洁易懂:

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

We can put it in a function:

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

我最近切换到设置 strong-mode-version 2.0,我的 null 测试失败了。

我添加了一个函数:

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

Now I code

if (exists $run main) { ...

rather than

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

and we are on our way. Seems to work on objects and hashtables

作为一个意想不到的好处,它减少了输入。

你可以查询:

这将检查 Name 属性

For identifying which of the objects in an array have a property

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

然而,对我来说 MyProperty" -in $MyObject.PSobject.Properties.Name不起作用

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

工程

对于一个严格安全的一行程序,请尝试这样做。

[bool]$myobject.PSObject.Properties[$propertyName]

例如:

Set-StrictMode -Version latest;
$propertyName = 'Property1';
$myobject = [PSCustomObject]@{ Property0 = 'Value0' };


if ([bool]$myobject.PSObject.Properties[$propertyName]) {
$value = $myobject.$propertyName;
}

for me this work

Set-StrictMode -Version Latest
$TMP = ...


$HAS_SERVERS=($TMP | Select-Object Servers)
if (-not $HAS_SERVERS.Servers){
echo "No servers. Abort."
} else {
...
}
 

我发现这种方法在检查多个属性时更严格、更快

$null -ne $myobject.PSObject.Properties.Item("myPropertyNameToTest")

There are a number of solutions to this question that work in strict mode, but some are better than others.

似乎没有遍历每个属性的解决方案是最快的解决方案。

  1. 伯尼 · 怀特的解决方案
  2. 埃斯卡尔溶液(修改后)

看起来像是在每个属性中迭代的解决方案速度较慢。

  1. 赛贝克 CCU 的解决方案
  2. Dan-Gph 的解决方案

似乎遍历每个属性并使用正则表达式的解决方案比前两个解决方案稍慢一些(因为编译和执行正则表达式需要更多的时间)

  1. CB 的解决方案

使用 GetMethod 的解决方案似乎会遍历每个属性,但使用 GetMethod会使其显著减慢。

  1. Paul's GetMethod solution

The following script was used to compare the previously mentioned solutions in strict mode:

# Tested in PowerShell core 7.2.0


Set-StrictMode -Version Latest


$propertyExistsMethods = New-Object System.Collections.Generic.Dictionary'[string,scriptblock]'


# Fastest
$propertyExistsMethods.Add(
"PSObject.Properties (Bernie White's solution)",
{
Param( [PSObject] $Object, [string] $Property )
[bool]$Object.PSObject.Properties[$Property]
})
$propertyExistsMethods.Add(
"PSObject.Properties.Item (esskar's solution (modified))",
{
Param( [PSObject] $Object, [string] $Property )
[bool]$Object.PSObject.Properties.Item($property)
})


# Not as fast
$propertyExistsMethods.Add(
"Contains (sebke CCU's solution)",
{
Param( [PSObject] $Object, [string] $Property )
$Object.PSobject.Properties.Name.Contains($Property)
})
$propertyExistsMethods.Add(
"-in (dan-gph's solution)",
{
Param( [PSObject] $Object, [string] $Property )
$Property -in $Object.PSobject.Properties.Name
})


# Slower than the previously mentioned solutions
$propertyExistsMethods.Add(
"-match (CB.'s solution)",
{
Param( [PSObject] $Object, [string] $Property )
[bool]($Object.PSobject.Properties.name -match $Property)
})


# Slowest
$propertyExistsMethods.Add(
"GetMember (Paul's solution)",
{
Param( [PSObject] $Object, [string] $Property )
Get-Member -inputobject $Object -name $Property -Membertype Properties
})


foreach ($method in $propertyExistsMethods.Keys) {
$propertyExists = $propertyExistsMethods[$method]


$o = @{}
foreach ($i in 1..100000) {
$o[$i] = "p$i"
}


Write-Host $method
$measure = Measure-Command {
foreach ($i in 1..100000) {
# Always check for a property that does NOT exist
& $propertyExists -Object $o -Property 'p'
}
}
Write-Host $measure | % { $_.Milliseconds }
Write-Host ''
}

产出如下:

PSObject.Properties (Bernie White's solution)
00:00:03.1437587


PSObject.Properties.Item (esskar's solution)
00:00:03.5833642


Contains (sebke CCU's solution)
00:00:04.4812702


-in (dan-gph's solution)
00:00:04.6507811


-match (CB.'s solution)
00:00:05.1107066


GetMember (Paul's solution)
00:00:14.5305115