为什么 PowerShell [TYPE]::new() 是小写
Why is PowerShell [TYPE]::new() lower case
我注意到但从未见过任何解释的是这个奇怪的小“事实”。
我可以从 Powershell 调用的大多数(全部?)class 方法都使用 Pascal Case。例如
[System.IO.FileInfo].FullName
$xmlWriter.WriteStartDocument()
[System.GC]::Collect()
还有更多。但我一直看到的一个例外是新的。 New 是(几乎?)总是小写的。输入 [xml.xmlReaderSettings]::
,提供的有用下拉列表为 Equals
、new
和 ReferenceEquals
。
这种情况一直发生,我怀疑这不是巧合,所以我希望有人能解释为什么。
我的想法是,由于命名约定是 Public 方法和参数使用 Pascal 大小写(而私有方法和参数使用 Camel 大小写)并且 []::new 既不是 属性 也不是参数,它是对构造函数的间接调用,它有驼峰式大小写吗?或者甚至不是驼峰式大小写,只是小写,在这种情况下看起来是一样的。
我知道在PowerShell中这并不重要,只是好奇底层逻辑是什么。
new
是 lower-case 因为 new
是 special
这个答案部分基于我与一些相关方(即 Microsoft 的 PowerShell(前)团队成员)的对话,所以它更多的是轶事虚构这不是硬性的技术事实,但这就是一些“为什么他们做 X 而不是 Y”问题的本质
TL;DR:
您的推理是合理的,但这不像微软内部的一个委员会坐下来查看 .NET 规范并决定“如果我们引入合成构造函数调用方法,我们必须打破这些命名约定,本着定义标准的精神” - 与现实生活中的大多数事情一样,这个决定受到多种因素的影响,我将在下面重述其中的一些。
正如您在问题中指出的那样,new
与其他人不同 - 静态成员调用运算符 (::
) 仅公开 public 静态成员,.NET 命名约定为 public 成员规定了 PascalCase
的名称。
但是 new
打破了这一惯例,要理解 为什么 您需要查看它在 PowerShell 5.0
中的起源和介绍的上下文
用于对象分配的 new
关键字的来源
在 PowerShell 上下文中使用名称或关键字 new
直接从 C#
!
中取消
new
作为关键字嵌入到 C# 语言语法中,它最 well-known 的应用是通过调用适当的构造函数来实例化新的对象实例:
var instance = new TypeName();
C# 又从 C++ 中获取了 new
,C++ 是一种用于类似目的的语言,为类型化对象自动分配内存:
T instance = new TypeName;
C++ 又从 SmallTalk 中获取了 new
,这是我所知道的最古老的语言,它积极地将其用于对象分配:
instance := TypeName new
SmallTalk 的作者使用 new
可能只是因为他们认为它符合目的,但也可以想象他们从 ALGOL68 中获得灵感,我在其中理解 new
是array-generating 过程的通用运算符名称(这部分是 100% 的轶事推测,我从未写过或 运行 任何 ALGOL)。
无论如何,使用小写 new
来命名内存中分配对象的过程具有 50 年的历史。
PowerShell <5.0 中的构造函数调用
在 PowerShell 5.0 中引入此 new
quasi-method 之前,调用 .NET 构造函数的惯用方法是让 New-Object
处理它:
$instance = New-Object -TypeName 'Target.Type.Name' -ArgumentList @($ctorParamArgs,$go,$here)
New-Object
在 2.0 的初始版本中对这两个参数进行了位置绑定,希望这个 new-fangled 和闪亮的 但非常冗长 ,脚本语言将吸引 .NET 生态系统的现有用户,尤其是已经熟悉 C# 的开发人员和系统管理员:
# Lot's of typing on the keyboard in PowerShell ...
New-Object -TypeName 'TypeName' -ArgumentList @($arg)
# ... compared to C#
new TypeName(arg);
# The compromise - New-Object invoked with positional binding:
New-Object TypeName $arg
但一些开发人员仍然觉得 PowerShell 的命令表达式语法过于冗长,不久之后,互联网上的脚本共享存储库中充斥着滥用 Alias
功能模仿 C# 的脚本:
Set-Alias new New-Object
new TypeName($arg) # doesn't get much closer and this
所以 new
,作为一个(假的)“构造函数关键字”,早在 PowerShell 3.0 发布之前就已经存在于围绕 PowerShell 的社区生态系统中,并且一部分用户显然渴望更多分配新对象的简洁方法。
PowerShell 5.0 和 class
定义的出现
PowerShell 5.0 的一个主要功能是引入了 enum
和 class
关键字,PowerShell 用户突然可以使用它们 定义自己的 CTS-compliant数据类型!
能够在运行时定义新类型很棒,但当然您需要能够使用它们 - 那么有哪些选项可用?
New-Object
- 可以实例化 PowerShell 类 就好了,但是让 语言本身 能够 定义感觉很尴尬 类型,但没有 built-in 实例化它们的工具。
- 在语法中引入
new
作为新关键字 - 除了,与上一节中描述的滥用别名功能的现有脚本的兼容性如何 - 如果新的 new
表达式支持@()
参数列表?
- 引入
new
作为类型文字上的合成静态成员名称 - 事实证明这比你想象的更好的兼容性 - New
作为成员名称在.NET 生态系统(Create()
是 user-defined 构造函数包装器的规范偏好),因此可以在根本不改变语言的情况下进行更改 - 只需在 ::
调用成员运算符的成员名称为 new
. 时的实现
PowerShell 团队最终选择了后者,并决定按照上面讨论的祖先语言的风格将其保留为小写,这反过来又发送了您收到的消息 - 这条消息与其他消息不同 :)
我注意到但从未见过任何解释的是这个奇怪的小“事实”。 我可以从 Powershell 调用的大多数(全部?)class 方法都使用 Pascal Case。例如
[System.IO.FileInfo].FullName
$xmlWriter.WriteStartDocument()
[System.GC]::Collect()
还有更多。但我一直看到的一个例外是新的。 New 是(几乎?)总是小写的。输入 [xml.xmlReaderSettings]::
,提供的有用下拉列表为 Equals
、new
和 ReferenceEquals
。
这种情况一直发生,我怀疑这不是巧合,所以我希望有人能解释为什么。
我的想法是,由于命名约定是 Public 方法和参数使用 Pascal 大小写(而私有方法和参数使用 Camel 大小写)并且 []::new 既不是 属性 也不是参数,它是对构造函数的间接调用,它有驼峰式大小写吗?或者甚至不是驼峰式大小写,只是小写,在这种情况下看起来是一样的。
我知道在PowerShell中这并不重要,只是好奇底层逻辑是什么。
new
是 lower-case 因为 new
是 special
这个答案部分基于我与一些相关方(即 Microsoft 的 PowerShell(前)团队成员)的对话,所以它更多的是轶事虚构这不是硬性的技术事实,但这就是一些“为什么他们做 X 而不是 Y”问题的本质
TL;DR:
您的推理是合理的,但这不像微软内部的一个委员会坐下来查看 .NET 规范并决定“如果我们引入合成构造函数调用方法,我们必须打破这些命名约定,本着定义标准的精神” - 与现实生活中的大多数事情一样,这个决定受到多种因素的影响,我将在下面重述其中的一些。
正如您在问题中指出的那样,new
与其他人不同 - 静态成员调用运算符 (::
) 仅公开 public 静态成员,.NET 命名约定为 public 成员规定了 PascalCase
的名称。
但是 new
打破了这一惯例,要理解 为什么 您需要查看它在 PowerShell 5.0
用于对象分配的 new
关键字的来源
在 PowerShell 上下文中使用名称或关键字 new
直接从 C#
!
new
作为关键字嵌入到 C# 语言语法中,它最 well-known 的应用是通过调用适当的构造函数来实例化新的对象实例:
var instance = new TypeName();
C# 又从 C++ 中获取了 new
,C++ 是一种用于类似目的的语言,为类型化对象自动分配内存:
T instance = new TypeName;
C++ 又从 SmallTalk 中获取了 new
,这是我所知道的最古老的语言,它积极地将其用于对象分配:
instance := TypeName new
SmallTalk 的作者使用 new
可能只是因为他们认为它符合目的,但也可以想象他们从 ALGOL68 中获得灵感,我在其中理解 new
是array-generating 过程的通用运算符名称(这部分是 100% 的轶事推测,我从未写过或 运行 任何 ALGOL)。
无论如何,使用小写 new
来命名内存中分配对象的过程具有 50 年的历史。
PowerShell <5.0 中的构造函数调用
在 PowerShell 5.0 中引入此 new
quasi-method 之前,调用 .NET 构造函数的惯用方法是让 New-Object
处理它:
$instance = New-Object -TypeName 'Target.Type.Name' -ArgumentList @($ctorParamArgs,$go,$here)
New-Object
在 2.0 的初始版本中对这两个参数进行了位置绑定,希望这个 new-fangled 和闪亮的 但非常冗长 ,脚本语言将吸引 .NET 生态系统的现有用户,尤其是已经熟悉 C# 的开发人员和系统管理员:
# Lot's of typing on the keyboard in PowerShell ...
New-Object -TypeName 'TypeName' -ArgumentList @($arg)
# ... compared to C#
new TypeName(arg);
# The compromise - New-Object invoked with positional binding:
New-Object TypeName $arg
但一些开发人员仍然觉得 PowerShell 的命令表达式语法过于冗长,不久之后,互联网上的脚本共享存储库中充斥着滥用 Alias
功能模仿 C# 的脚本:
Set-Alias new New-Object
new TypeName($arg) # doesn't get much closer and this
所以 new
,作为一个(假的)“构造函数关键字”,早在 PowerShell 3.0 发布之前就已经存在于围绕 PowerShell 的社区生态系统中,并且一部分用户显然渴望更多分配新对象的简洁方法。
PowerShell 5.0 和 class
定义的出现
PowerShell 5.0 的一个主要功能是引入了 enum
和 class
关键字,PowerShell 用户突然可以使用它们 定义自己的 CTS-compliant数据类型!
能够在运行时定义新类型很棒,但当然您需要能够使用它们 - 那么有哪些选项可用?
New-Object
- 可以实例化 PowerShell 类 就好了,但是让 语言本身 能够 定义感觉很尴尬 类型,但没有 built-in 实例化它们的工具。- 在语法中引入
new
作为新关键字 - 除了,与上一节中描述的滥用别名功能的现有脚本的兼容性如何 - 如果新的new
表达式支持@()
参数列表? - 引入
new
作为类型文字上的合成静态成员名称 - 事实证明这比你想象的更好的兼容性 -New
作为成员名称在.NET 生态系统(Create()
是 user-defined 构造函数包装器的规范偏好),因此可以在根本不改变语言的情况下进行更改 - 只需在::
调用成员运算符的成员名称为new
. 时的实现
PowerShell 团队最终选择了后者,并决定按照上面讨论的祖先语言的风格将其保留为小写,这反过来又发送了您收到的消息 - 这条消息与其他消息不同 :)