powershell - 区分 PowerShell 中不同类型的哈希表?
问题描述
看起来 PowerShell 中有不同类型的哈希表,有区分大小写的,有的不区分大小写。如下定义哈希表时,它不区分大小写:
$ht = @{ "Test" = "HI" }
$ht.Contains("test") #returns true, even with key name lowercase
True
$ht.ContainsKey("test") #returns true, even with key name lowercase
True
$ht.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Hashtable System.Object
但是,如果您这样定义它,则区分大小写:
$ht_caseSensitive = New-Object System.Collections.Hashtable
$ht_caseSensitive.Add("Test", "HI")
$ht_caseSensitive.Contains("test") # returns false, since it's all lowercase
False
$ht_caseSensitive.ContainsKey("test") # returns false, same with contains key function
False
$ht_caseSensitive.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Hashtable System.Object
但是,如GetType()
输出所示,我似乎找不到区分这些对象的方法。
- 为什么一种区分大小写而另一种不区分?
- 当重要的是要知道我是否正在处理区分大小写的哈希表时,有什么方法可以区分它们吗?
解决方案
为什么一种区分大小写而另一种不区分?
因为PowerShell 经常故意将默认的 .NET 功能修改为不区分大小写,以保持 PowerShell整体不区分大小写。
因此,虽然哈希表文字
@{ "Test" = "HI" }
确实创建了一个[hashtable]
(System.Collections.Hashtable
) 实例,但 PowerShell在幕后使用显式不区分大小写的相等比较器来构造它。[1]相比之下,构造
[hashtable]
实例直接遵循.NET 的默认值,即简单地调用.Equals()
键查找方法,在字符串键的情况下(典型情况)相当于顺序的、区分大小写的比较。
当重要的是要知道我是否正在处理区分大小写的哈希表时,有什么方法可以区分它们吗?
如果您始终使用 PowerShell 哈希表文字和/或通过文字构造(初始化)哈希表@{}
,您将始终获得不区分大小写的查找。
如果您仍然需要反映给定[hashtable]
实例以确定其相等比较器是否区分大小写,您可以使用以下 - 模糊 - 技术:
# Create a case-SENSITIVE hashtable.
# Note: in PowerShell v5+, the more efficient alternative is:
# $someHashTable = [hashtable]::new()
$someHashTable = New-Object hashtable # System.Collections.Hashtable
# Use reflection to get the *non-public* (protected, in this case)
# .EqualityComparer property value.
$equalityComparer = [hashtable].GetProperty(
'EqualityComparer',
[System.Reflection.BindingFlags]'NonPublic, Instance'
).GetValue($someHashTable)
# The hashtable is case-sensitive if it either doesn't define
# an explicit comparer or uses one that is case-sensitive.
$isCaseSensitive = $null -eq $equalityComparer -or
0 -ne $equalityComparer.Compare('a', 'A')
[1] 在Windows PowerShell(最高 v5.1 的版本)中,这个比较器 - 令人惊讶的是 -文化敏感的;在 PowerShell [Core] v7.0 中,它使用序数(但仍不区分大小写)比较。请注意,在许多其他情况下,PowerShell 改为使用文化不变的行为 - 请参阅此答案。
推荐阅读
- react-native - React Native Camera 能够捕捉图像但不能录制视频
- django - 模型中的实用程序:可接受与否?
- c# - 如何通过 Azure Batch SDK 将文件上传到 Azure Batch 自动存储?
- laravel - laravel 8:插入方法在 eloquent 中获取最后一个插入 id(插入方法)
- javascript - 如何将错误/验证文本移动到输入框的底部?
- r - ggplot标签上的卷曲卷曲
- excel - 需要在 excel 中编写公式以仅返回索引匹配公式中的唯一值
- php - 如果一个项目中有多项费用,我如何将它们加在一起并排成一行?
- excel - 很难在 Excel 中找出用于修剪符号并移动到下一行的公式
- docker - Docker 文件没有执行 CMD 部分