get_Keys()
确实是一种有效的(也是推荐的)访问方式the Keys财产字典的内容,而不会有与用户定义的键发生冲突的风险。
该方法按预期工作(也适用于其他集合、任何 PowerShell 版本和 .Net Core):
请注意,这仅适用于字典 ([hashtable]
, [ordered]
, [SortedList]
等) - 因为它继承自the System.Collections.IDictionary界面.
原因get_Keys()
公共文档中没有列出的是它故意隐藏.
要了解其原因,我们首先需要了解其本质特性 in .NET
.NET 中的属性
在 .NET 中,数据类型可以有不同种类members。在下面的 (C#) 示例中,我们定义一个具有两个成员的类,一个field and a method:
class MyClass
{
int MyField;
int MyMethod(string n = "")
{
return int.Parse(n);
}
}
这里值得注意的有趣的事情是,该字段就像变量一样- 我们可以引用它来获取存储在其中的任何整数的值MyField
我们可以为其分配一个(新)值。另一方面,该方法就像一个函数一样- 我们可以调用它,包括向它传递参数值,并且它可以返回一个值。
但是 .NET 有第三种成员类型,它的作用有点像hybrid在字段和方法之间,它看起来有点像这样(在字典的情况下):
class MyDictionary
{
string[] _keys;
public string[] Keys
{
get
{
return _keys;
}
set
{
throw new InvalidOperationException("Don't mess with the keys!");
}
}
}
这被称为property- 从用户的角度来看,Keys
属性的行为就像一个字段 - 我们可以引用它来解析它的值,并且我们可以(尝试)分配给它 - 但从实现者的角度来看,我们对其行为有更多的控制,比如能够(有条件地)抛出分配时的例外情况。
现在,当编译上面的代码时,C#编译器需要存储get
and set
方法某处以便 CLR 知道当有人尝试解决问题时要执行它们Keys
运行时的成员。
约定是将它们生成为常规类方法,通过前缀命名get_
and set_
到有问题的属性名称。编译器进一步用以下标记这些方法SpecialName属性标志,允许编辑器和分析器将它们隐藏在用户界面和自动完成器中 - 这正是方法名称不会自动显示在智能感知等中的原因。
发现属性 getter/setter
*在 PowerShell 类中,成员始终是methods or 特性,因此在下面我将使用此 PowerShell 类定义作为示例:
class StackOverflowUser
{
[string]$Name
[int]$ID
StackOverflowUser([string]$name, [int]$id)
{
$this.Name = $name
$this.ID = $ID
}
}
$Mathias = [StackOverflowUser]::new("Mathias R. Jessen", 712649)
Using Get-Member
您可以使用以下方法发现与属性关联的自动 getter 和 setterGet-Member -Force
:
PS C:\> $Mathias |Get-Member ?et_* -Force
TypeName: StackOverflowUser
Name MemberType Definition
---- ---------- ----------
get_ID Method int get_ID()
get_Name Method string get_Name()
set_ID Method void set_ID(int )
set_Name Method void set_Name(string )
在这里我们可以看到与相关的 getter 和 setter 方法$ID
and $Name
.
使用反射
我们也可以直接从[type]
object:
PS C:\> $IDPropertyInfo = [StackOverflowUser].GetProperty("ID")
PS C:\> $IDPropertyInfo.GetMethod
Name : get_ID
DeclaringType : StackOverflowUser
ReflectedType : StackOverflowUser
MemberType : Method
MetadataToken : 100663299
Module : RefEmit_InMemoryManifestModule
IsSecurityCritical : True
IsSecuritySafeCritical : False
IsSecurityTransparent : False
MethodHandle : System.RuntimeMethodHandle
Attributes : PrivateScope, Public, HideBySig, SpecialName
CallingConvention : Standard, HasThis
ReturnType : System.Int32
ReturnTypeCustomAttributes : Int32
ReturnParameter : Int32
IsCollectible : True
IsGenericMethod : False
IsGenericMethodDefinition : False
ContainsGenericParameters : False
MethodImplementationFlags : Managed
IsAbstract : False
IsConstructor : False
IsFinal : False
IsHideBySig : True
IsSpecialName : True
IsStatic : False
IsVirtual : False
IsAssembly : False
IsFamily : False
IsFamilyAndAssembly : False
IsFamilyOrAssembly : False
IsPrivate : False
IsPublic : True
IsConstructedGenericMethod : False
CustomAttributes : {}
请注意,上面的 getter 有SpecialName
如上所述的属性
注意:上面的输出来自 PowerShell 7,将是slightly由于 .NET Core 中反射/类型系统 API 的更改,Windows PowerShell 中有所不同
我希望这能解释:)