.net 什么';@{}和[Hashtable]::Clear()之间的区别是什么?

.net 什么';@{}和[Hashtable]::Clear()之间的区别是什么?,.net,powershell,.net,Powershell,全部 我正在编写代码,将标准INI文件结构转换为基于哈希表和数组的结构。例如,INI代码段如下所示: [Book] title="Moby Dick" author="Herman Melville" genre=fiction genre=fantasy [Book] title="James and the Giant Peach" author="Roald Dahl" genre="fiction" 看起来像: @{ "Book" = [ @{

全部

我正在编写代码,将标准INI文件结构转换为基于哈希表和数组的结构。例如,INI代码段如下所示:

[Book]
title="Moby Dick"
author="Herman Melville"
genre=fiction
genre=fantasy

[Book]
title="James and the Giant Peach"
author="Roald Dahl"
genre="fiction"
看起来像:

@{
    "Book" = [
        @{
            "title" = ["Moby Dick"];
            "author" = ["Herman Melville"];
            "genre" = ["fiction","fantasy"]
        },
        @{
            "title" = ["James and the Giant Peach"];
            "author" = ["Roald Dahl"];
            "genre" = ["fiction"]
        }
    ]

}
我想解释具有多个同名部分和具有多个同名属性的部分的INI文件,因此是这种数据结构。我知道我可以用一棵树来做同样的事情,但我不太在乎它的速度,在我写它的时候,这更容易实现

这是通过更新一个哈希表来实现的,该哈希表将节中的所有属性与其值关联(我们称之为
$items
),然后更新将每个节与上述哈希表关联的主哈希表(我们称之为
$results
)。哈希表是全局的,属性哈希表在迭代到新部分时被清除

虽然我编写的代码可以做到这一点,而且工作得很好,但对于Powershell清除哈希表的方式,我被难住了几分钟。如果我使用
$items.clear()
清除
$items
$results
中所有元素关联的哈希表也会被清除。
但是,如果我通过声明
$items=@{}
来“清除”它,则不会发生这种情况

我假设发生这种情况是因为前一种情况下的哈希表都是对全局哈希表的引用,在后一种情况下是独立的对象。这是怎么回事

代码如下;很抱歉,如果有任何问题让人困惑(而且它不是典型的Powershell语法)。将
$items=@{}
替换为
$items=$items.Clear()
以复制:

function parse ($file) {
    $result = @{}
    if (!(Test-Path $file)) {   
        write-host "File does not exist: $file"
    } elseif (!($data = cat $file)) {
        write-host "File has no data: $file"
    } else {
        $last_value = ""
        $last_data = ""
        $items = @{}
        foreach ($line_raw in $data | ?{$_.Trim().Length -gt 0}) {
            $line = $line_raw.TrimStart().TrimEnd()
            $first_char = $line[0]
            switch ($first_char) {
                ';' { 
                    continue 
                }
                '[' {
                    $key = $line -replace "\[|\]",""
                    if ($last_key) {
                        if (!($result.ContainsKey($last_key)))
                            { $result.Add($last_key,@($items)) }
                        else
                            { $result[$last_key] += $items }
                        if ($last_key -ne $key) 
                            { $items = @{} }                    
                    }
                    $last_key = $key
                }
                default {
                    $item , $data = $(
                        $sep = $line.indexOf('=')
                        $line.substring(0,$sep) , $line.substring($sep+1)
                    )
                    if (!$items.ContainsKey($item))
                        { $items.Add($item,@($data))    }
                    else 
                        { $items[$item] += $data }
                }
            }
        }
        $result
    }
}

类似于
$items
的变量引用的存储位置在本例中包含哈希表。当您将变量赋值为
@{}
时,您将为变量赋值一个对新的空哈希表的引用。如果没有其他内容引用原始哈希表,垃圾收集器将回收其内存。在哈希表上执行
Clear()
方法会使其重置为空状态。

类似于
$items
的变量指的是在本例中包含哈希表的存储位置。当您将变量赋值为
@{}
时,您将为变量赋值一个对新的空哈希表的引用。如果没有其他内容引用原始哈希表,垃圾收集器将回收其内存。在哈希表上执行
Clear()
方法会使其重置为空状态。

首先,我认为您的意思是:$items.Clear()而不是$items=$items.Clear()


我必须仔细看看,因为我还没有发现任何可疑的东西,但我只是想让你知道,回答一个更基本的问题,当应用于内存中的哈希表和正在存储的文件时,上面的所有代码都可以通过ConvertTo-Json和ConvertFrom-Json cmdlet在Powershell中使用几行代码实现。试一试,你就会明白我的意思。

首先,我想你的意思是:$items.Clear()而不是$items=$items.Clear()


我必须仔细看看,因为我还没有发现任何可疑的东西,但我只是想让你知道,回答一个更基本的问题,当应用于内存中的哈希表和正在存储的文件时,上面的所有代码都可以通过ConvertTo-Json和ConvertFrom-Json cmdlet在Powershell中使用几行代码实现。试一试,你就会明白我的意思。

我似乎无法复制这种行为。你能把如何设置不同哈希表的代码发出来吗?我似乎无法复制这种行为。你能把你如何设置不同哈希表的代码贴出来吗?谢谢!你说得对,我的意思是
$items.Clear()。
这与数据的结构有关吗?我还以为它包含在Powershell v3+中。是的。看一看它是如何将哈希表转换成和转换成数据的。我认为您可以使用v3,因为我没有看到任何相反的情况。如果不是这样的话,你真的应该在问题中包含这种类型的约束。谢谢!你说得对,我的意思是
$items.Clear()。
这与数据的结构有关吗?我还以为它包含在Powershell v3+中。是的。看一看它是如何将哈希表转换成和转换成数据的。我认为您可以使用v3,因为我没有看到任何相反的情况。如果不是这样的话,你应该在问题中加入这种约束。是的,我想这就是发生的事情。再次感谢你,基思!作为附带问题,这是使用Powershell解析INI文件的推荐方法吗?虽然脚本编写人员的示例使用了更简单的代码,但它似乎没有将属性与其值相关联,尽管它确实将节与属性相关联。提前谢谢!是的,我想这就是发生的事情。再次感谢你,基思!作为附带问题,这是使用Powershell解析INI文件的推荐方法吗?虽然脚本编写人员的示例使用了更简单的代码,但它似乎没有将属性与其值相关联,尽管它确实将节与属性相关联。提前谢谢!