如何测试对象是否具有特定属性?
欣赏我能做到......
$members = Get-Member -InputObject $myobject
然后foreach
通过$members
,但有一个函数来测试对象是否具有特定的属性?
附加信息:问题是我正在导入两种不同类型的CSV文件,一种是两列,另一种是三列。我无法使用“Property”进行检查,只能使用“NoteProperty”...无论差异是什么
if ( ($member.MemberType -eq "NoteProperty" ) -and ($member.Name -eq $propertyName) )
像这样?
[bool]($myObject.PSobject.Properties.name -match "myPropertyNameToTest")
我刚开始使用PowerShell与PowerShell Core 6.0(测试版),以下简单的工作:
if ($members.NoteProperty) {
# NoteProperty exist
}
要么
if (-not $members.NoteProperty) {
# NoteProperty does not exist
}
我最近切换到设置strict-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
}
现在我编码
if (exists $run main) { ...
而不是
if ($run.main -ne $null) { ...
我们正在路上似乎可以处理对象和哈希表
作为一种意想不到的好处,它更少打字。
用于标识数组中的哪些对象具有属性
$HasProperty = $ArrayOfObjects | Where-Object {$_.MyProperty}
您可以查看:
($Member.PropertyNames -contains "Name")
这将检查Named属性
你可以使用Get-Member
if(Get-Member -inputobject $var -name "Property" -Membertype Properties){
#Property exists
}
这简洁易读:
"MyProperty" -in $MyObject.PSobject.Properties.Name
我们可以把它放在一个函数中:
function HasProperty($object, $propertyName)
{
$propertyName -in $object.PSobject.Properties.Name
}
我一直在使用以下返回属性值,因为它将通过$thing.$prop
访问,如果“属性”将存在而不抛出随机异常。如果属性“不存在”(或具有空值)则返回$null
:这种方法在/中对于严格模式有用,因为,好吧,它会全部捕获它们。
我发现这种方法很有用,因为它允许PS自定义对象,普通的.NET对象,PS HashTables和像Dictionary这样的.NET集合被视为“鸭型等效”,我发现它非常适合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"]
。
如果您使用的是StrictMode且psobject可能为空,则会出现错误。
出于所有目的,这将做:
if (($json.PSobject.Properties | Foreach {$_.Name}) -contains $variable)
真正类似于javascript检查:
foreach($member in $members)
{
if($member.PropertyName)
{
Write $member.PropertyName
}
else
{
Write "Nope!"
}
}
只是为了澄清给出以下对象
$Object
具有以下属性
type : message
user : [email protected]
text :
ts : 11/21/2016 8:59:30 PM
以下是真实的
$Object.text -eq $NULL
$Object.NotPresent -eq $NULL
-not $Object.text
-not $Object.NotPresent
因此,通过名称显式检查属性的早期答案是验证该属性不存在的最正确方法。
只需检查null即可。
($myObject.MyProperty -ne $null)
如果你没有set PowerShell to 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
我最终得到了以下功能......
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;
}
}