Почему `[SomeType] | Get-Member -Static` возвращает данные c членов `SomeType` вместо членов` System.RuntimeType`? - PullRequest
1 голос
/ 04 мая 2020

Давайте рассмотрим пример. Если вы правильно понимаете, System.IO.FileStream - это класс, но [System.IO.FileStream] - это объект: это экземпляр класса System.RuntimeType.

. Если я запусту [System.IO.FileStream] | Get-Member, я получу члены System.RuntimeType (технически, его экземпляра):

   TypeName: System.RuntimeType

Name                           MemberType Definition
----                           ---------- ----------
AsType                         Method     type AsType()
Clone                          Method     System.Object Clone()
Equals                         Method     bool Equals(System.Object obj), bool Equals(type o)
FindInterfaces                 Method     type[] FindInterfaces(System.Reflection.TypeFilter filter, System.Object filterCriteria)
...
TypeHandle                     Property   System.RuntimeTypeHandle TypeHandle {get;}
TypeInitializer                Property   System.Reflection.ConstructorInfo TypeInitializer {get;}
UnderlyingSystemType           Property   System.Type UnderlyingSystemType {get;}

Согласно документации :

Чтобы получить информацию о членах c, члены класса, а не экземпляра, используют параметр Stati c.

Но если я запускаю [System.IO.FileStream] | Get-Member -Static, теперь я получаю:

   TypeName: System.IO.FileStream

Name            MemberType Definition
----            ---------- ----------
Equals          Method     static bool Equals(System.Object objA, System.Object objB)
ReferenceEquals Method     static bool ReferenceEquals(System.Object objA, System.Object objB)
Synchronized    Method     static System.IO.Stream Synchronized(System.IO.Stream stream)
Null            Property   static System.IO.Stream Null {get;}

Q1. Это члены c членов System.IO.FileStream, а не System.RuntimeType. Почему это так?

В документации также говорится:

Мы используем :: , чтобы указать Windows PowerShell что мы хотим работать с методом или свойством stati c.

Это заставило меня понять, что [System.IO.FileStream]::Null относится к свойству stati c Null класса System.IO.FileStream.

Q2. Означает ли это, что Powershell иногда видит [System.IO.FileStream] как класс System.IO.FileStream (при работе с членами stati c), а иногда как экземпляр System.RuntimeType?

1 Ответ

2 голосов
/ 04 мая 2020

По умолчанию Get-Member без -Static всегда действует на тип его входных объектов .

[System.IO.FileStream] - это экземпляр литерала типа PowerShell ([<type-name>]), чей тип равен System.RuntimeType Это внутренний класс PowerShell, производный от System.Reflection.TypeInfo и в конечном итоге System.Type.

Следовательно, [System.IO.FileStream] | Get-Member выводит информацию о членах System.RuntimeType - и так будет любой литерал типа (например, [int] | Get-Member даст тот же результат).


В отличие от Get-Member с -Static:

  • воздействует на сам объект ввода , если это System.RunTimeType экземпляр типа литерала типа [System.IO.FileStream]; в противном случае, как обычно, используется тип объекта ввода .

  • сообщает только о stati c членах объекта ввода / type.

Следовательно, [System.IO.FileStream] | Get-Member -Static сообщает о состоянии c членов типа System.IO.FileStream - как при передаче экземпляра из тип System.IO.FileStream; Например, [System.IO.FileStream]::new($PROFILE, 'Open') | Get-Member -Static


Любопытное упущение, с PowerShell Core 7.0 , заключается в том, что вы не можете использовать Get-Member для запроса экземпляр члены по типу ; единственный способ получить члены экземпляра типа - передать фактический экземпляр в качестве входных данных; однако проблема в том, что не всегда легко получить экземпляр, поэтому было бы полезно получить членов экземпляра по типу, что эта проблема GitHub запрашивает.

Тем временем вы можете наберите .GetMembers() для типа, как вы продемонстрируете в своем собственном ответе здесь .

...