将get_Keys()方法用于集合是否正确? [英] Is it correct to use the get_Keys() method for collections

查看:194
本文介绍了将get_Keys()方法用于集合是否正确?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有关此问题:是否可以在不覆盖'keys'成员的情况下将名为'keys'的键添加到哈希表中 ,实际上我经常使用get_Keys() 方法,因为推荐的PSBase 属性只会解决问题.
换句话说,在以下解决方案的情况下,此方法似乎对于目录密钥的未知列表特别方便: Powershell Merge 2列出了性能.

Related to this question: Can I add a key named 'keys' to a hashtable without overriding the 'keys' member , I am actually often using the get_Keys() method as the recommended PSBase property will just move the problem.
In other words, this method appears especially handy for an unknown list of directory keys in case of a solution like: Powershell Merge 2 lists Performance.

该方法可以按预期工作(也适用于其他集合,任何PowerShell版本和.Net Core):

The method works as expected (also on other collections, any PowerShell version and .Net Core):

$Hash = @{Keys = 'MyKeys'; PSBase = 'MyPSBase'}
$Hash.get_Keys()
PSBase
Keys

get_Keys()方法显然源自:

$Hash.get_Keys

OverloadDefinitions
-------------------
System.Collections.ICollection get_Keys()
System.Collections.ICollection IDictionary.get_Keys()

关键是我找不到在哪里找到该get_Keys()方法的引用,并且几乎没有关于此方法的文档.
使用这种方法安全吗?

The point is that I can't find back where I found the referral to this get_Keys() method and there is hardly any documentation about this method.
Is it safe to use this method?

推荐答案

get_Keys()确实是访问字典的Keys属性,而又不会与用户定义的键发生冲突.

get_Keys() is indeed a valid (and recommended) way to access the Keys property of a dictionary without risking collision with a user-defined key.

该方法可以按预期工作(也适用于其他集合,任何PowerShell版本和.Net Core):

The method works as expected (also on other collections, any PowerShell version and .Net Core):

请注意,这仅适用于字典([hashtable][ordered][SortedList]等)-因为它是从

Please beware that this only works on dictionaries ([hashtable], [ordered], [SortedList] etc.) - as it's inherited from the System.Collections.IDictionary interface.

get_Keys()未在公共文档中列出的原因是有意隐藏.

The reason get_Keys() isn't listed in the public documentation is that it's intentionally hidden.

要了解原因,我们首先需要了解.NET中属性的性质

To understand why, we first need to understand the nature of properties in .NET

在.NET中,数据类型可以具有不同种类的成员.在下面的(C#)示例中,我们定义一个具有两个成员的类,一个成员是 field method :

In .NET, data types can have different kinds of members. In the (C#) example below we define a class with two members, a field and a method:

class MyClass
{
    int MyField;

    int MyMethod(string n = "")
    {
        return int.Parse(n);
    }
}

这里要注意的有趣一点是,字段的作用类似于变量-我们可以引用该字段来获取MyField中存储的任何整数的值,然后可以分配一个(新)有价值.另一方面,该方法的作用类似于函数-我们可以调用它,包括将参数值传递给它,并且它可以返回值.

The interesting thing to notice here is that the field acts like a variable - we can reference it to obtain the value of whatever integer is stored in MyField and we can assign a (new) value to it. The method, on the other hand, acts like a function - we can call it, including passing parameter values to it, and it can return a value.

但是.NET具有第三种成员类型,它作为字段和方法之间的 hybrid 的一部分,看起来有点像这样(对于字典而言) :

But .NET has a third kind of member type that acts as a bit of a hybrid between a field and a method, and it looks a bit like this (in the case of a dictionary):

class MyDictionary
{
    string[] Keys
    {
        string[] _keys;

        get
        {
            return _keys;
        }
        set
        {
            throw new InvalidOperationException("Don't mess with the keys!");
        }
    }
}

这称为属性-从用户的角度来看,Keys属性的作用类似于字段-我们可以引用它来解析其值,并且可以(尝试)分配做到这一点-但从实现者的角度来看,我们对其行为有更多的控制权,例如能够(有条件地)在赋值时抛出异常.

This is known as a property - from a user perspective, the Keys property will act just like a field - we can reference it to resolve its value and we can (attempt to) assign to it - but from an implementer's perspective we have a lot more control over it's behavior, like being able to (conditionally) throw an exception on assignment.

现在,在编译以上代码时,C#编译器需要将getset方法存储在某处,以便CLR在有人尝试解决Keys成员在运行时.

Now, when the above code is compiled, the C# compiler needs to store the get and set methods somewhere so that the CLR knows to execute them when someone tries to resolve the Keys member at runtime.

惯例是将它们生成为常规类方法,并在所涉及的属性名称前添加get_set_进行命名.编译器还使用 SpecialName属性标记这些方法标志,允许编辑器和分析器将它们隐藏在用户界面和自动完成器中-这就是为什么方法名称不会自动显示在intellisense等中的原因.

The convention is to generate them as regular class methods, named by prepending get_ and set_ to the property name in question. The compiler further marks these methods with the SpecialName attribute flag, allowing editors and analyzers to hide them in user interfaces and auto-completers - which is exactly why the method name doesn't automatically show up in intellisense and the likes.

*在PowerShell类中,成员始终是方法 properties ,因此在下面的示例中,我将使用此PowerShell类定义:

*In PowerShell classes, members are always either methods or properties, so in the following I'll use this PowerShell class definition for the examples:

class StackOverflowUser
{
  [string]$Name
  [int]$ID

  StackOverflowUser([string]$name, [int]$id)
  {
    $this.Name = $name
    $this.ID   = $ID
  }
}

$Mathias = [StackOverflowUser]::new("Mathias R. Jessen", 712649)

使用Get-Member

您可以使用Get-Member -Force发现与属性关联的自动获取器和设置器:

Using Get-Member

You can discover the automatic getters and setters associated with a property using Get-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 )

在这里,我们可以看到与$ID$Name相关的getter和setter方法.

Here we can see the getter and setter methods associated with $ID and $Name.

我们还可以直接从[type]对象中找到这些内容:

We can also find these directly from a [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           : {}

请注意,上述吸气剂具有如上所述的SpecialName属性

Notice that the getter above has the SpecialName attribute as discussed above

注意:上面的输出来自PowerShell 7,由于.NET Core中反射/类型系统API的更改

我希望这能解释:)

这篇关于将get_Keys()方法用于集合是否正确?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆