Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

about_Type_Operators needs clarifications, should mention interfaces #4524

Open
mklement0 opened this issue Jul 7, 2019 · 0 comments

Comments

Projects
None yet
2 participants
@mklement0
Copy link
Contributor

commented Jul 7, 2019

The about_Type_Operators topic states:

If the is a type that is derived from the [.NET Type], -is returns $True.

This is incomplete and therefore potentially confusing, in that if <input> is of the very RHS type itself, it - sensibly - also returns $true.

E.g., in 1 -is [int] the type of 1 is [int], it isn't derived from it.

It is also incomplete in that if the RHS is an interface, -is also returns $true if the LHS instance's type implements that interface:

E.g., 1, 2 -is [System.Collections.IList] is $true, because the LHS type is [object[]], and arrays implement the System.Collections.IList interface.

If the is a type that is derived from the [.NET Type] -as converts the input to the target type.

This is misleading, in that if the LHS instance is of the RHS type or derived from it, the LHS is passed through as-is, and no conversion takes place; e.g.:

PS> ((Get-Item /) -as [System.IO.FileSystemInfo]).GetType().FullName
System.IO.DirectoryInfo  # *Directory*Info, not base type *FileSystem*Info

The same applies if the RHS is an interface that the LHS instance's type implements; e.g.:

PS> (1, 2 -as [System.Collections.IList]).GetType().FullName
System.Object[]  # The original *array type*, not the IList interface

The only time an actual conversion takes place is if the RHS type is unrelated to the type of the LHS instance, but a conversion exists; e.g., 1 -as [decimal] truly converts the [int] instance to 1 to a [decimal] instance; type [int] does not derive from type [decimal], but a standard conversion exists, and it is therefore applied:

PS> (1 -as [decimal]).GetType().FullName
System.Decimal  # actual conversion to [decimal] took pkace

You can think of the behavior of -as as follows:

# $instance -as [someType]  is equivalent to:

# pass through, if:
# - already of that type
# - derived from that type, 
#  - if type is an interface, if it implements that interface
if ($instance -is [someType]) { $instance }
# convert, if possible; return $null, if not
else { try { [someType] $instance } catch { $null } } 

Version(s) of document impacted

  • Impacts 7 document
  • Impacts 6 document
  • Impacts 5.1 document
  • Impacts 5.0 document
  • Impacts 4.0 document
  • Impacts 3.0 document
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.