Powershell: When powershell class method has same name as property, the property disapear and is not accessible from any instance

Created on 7 Sep 2018  路  12Comments  路  Source: PowerShell/PowerShell

Hi,

When I have a powershell class, that has a method with the same name as one of it's properties, then the property disapear, and is not visible on any of the instances.

See examples below.

Steps to reproduce


Class Folder {

    $Name
    $Path
    [bool]$IsPresent

    [string]IsPresent(){

        return "woop"
    }
}


When looking using Get-Member, we can see that the property $IsPresent disapeared, but that method is still there:

[Folder]::New() | gm


   TypeName: Folder

Name        MemberType Definition                    
----        ---------- ----------                    
Equals      Method     bool Equals(System.Object obj)
GetHashCode Method     int GetHashCode()             
GetType     Method     type GetType()                
IsPresent   Method     string IsPresent()            
ToString    Method     string ToString()             
Name        Property   System.Object Name {get;set;} 
Path        Property   System.Object Path {get;set;

Expected behavior


[Folder]::New()

#Should return

Name Path IsPresent
---- ---- ---------
              False

Actual behavior


[Folder]::New()

#Returns

Name Path
---- ----

Environment data

I had the same behaviour on:

> $PSVersionTable
Name                           Value
----                           -----
PSVersion                      6.1.0-preview.1
PSEdition                      Core
GitCommitId                    v6.1.0-preview.1
OS                             Microsoft Windows 10.0.14393
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

and


Name                           Value                                                                                            
----                           -----                                                                                            
PSVersion                      5.1.14393.2339                                                                                   
PSEdition                      Desktop                                                                                          
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}                                                                          
BuildVersion                   10.0.14393.2339                                                                                  
CLRVersion                     4.0.30319.42000                                                                                  
WSManStackVersion              3.0                                                                                              
PSRemotingProtocolVersion      2.3                                                                                              
SerializationVersion           1.1.0.1                                                                                          

On Windows 10 and Windows Server 2012 R2

Workaround

The workaround would be to change the name of the method and ensure it is not identical to the property anymore:


Class Folder {

    $Name
    $Path
    [bool]$IsPresent

    [string]TestIsPresent(){

        return "woop"
    }
}


Issue-Bug WG-Engine

All 12 comments

That probably shouldn't be allowed... I think?

But if this arises, you should be able to access the property with $Object.PSObject.Properties.Where{$_.Name -eq 'PropertyName'}.Value

Also, any particular reason you're not using [System.IO.DirectoryInfo] instead of a custom class, just out of curiosity? 馃槃

@Stephanevg I don't see "Steps to reproduce".

@iSazonov sorry for that. I updated my original post.
But, as @vexx32 mentionned, it is perhaps a best practise not to have a method named as a property.
, It could be that it is then kind of a security mechanism, where PS simply removes the property.

But if that is the case, we should have at least some guidance somewhere (PSSCRiptAnalyzer?), or simply throw an error perhaps? as without anything, mentioning that it disapears clearly felt strange to me.

@Stephanevg Thanks for the update.

Seems we already have a similar registered Issue. (Please search.)
We have plans to enhance class support in PowerShell Core and I believe the issue could be fixed too.

FWIW this will also occur with other similar situations. For example, adding a key named "keys" to a hashtable will prevent listing the keys unless you go into .PSObject.Base.Keys or some such.

It's a generic issue with the binder, I'd say, honestly; there needs to be a robust method of specifying a property in cases like these.

@rjmholt I think make sense add the Issue in your check list for classes.

@vexx32 That hashtable example sounds not good. I would open a separate issue for that one and tag the @PowerShell/powershell-committee

(The issue may be generic, but fixing it once for everything sounds like a breaking change and I can just imagine needing to twist around it in 9 ways)

That hashtable example is not good, and very difficult to work around! I'll open another one.

C# doesn't allow this, we should error

@vexx32 I am not, this was just for an example case. I faced this issue in a more complex class, and wanted to narrow it down to the essentials of the problem ;)

I don't think we actually need to allow this behaviour. If this is a bad practice, why allow it? Totally ok with have more strict rules in the naming of the properties / methods of our classes.

I think that writing an error + mentioning it in the docs - somehwere - that it isn't allowed, would be sufficent, I guess.
Having it just disapear like that is just odd.

Yeah this shouldn't be allowed. Not a very good idea, haha!

Was this page helpful?
0 / 5 - 0 ratings