.net Dictionary.Clear与新字典()的区别

8iwquhpp  于 2023-02-20  发布在  .NET
关注(0)|答案(9)|浏览(215)

Dictionary.Clearnew Dictionary()在C#中的主要区别是什么?在哪些情况下推荐使用哪一种?

i7uaboj4

i7uaboj41#

Dictionary.Clear()将删除字典中的所有KeyValue对。执行new Dictionary()将创建字典的新示例。
当且仅当旧版本的字典没有被另一个引用作为根时,创建一个新字典将使整个字典及其内容(没有被其他引用作为根)可供GC清理。
Dictionary.Clear()将使KeyValue对可用于清除。
在实践中,这两个选项往往会有非常相似的效果,不同之处在于在方法中使用时会发生什么:

void NewDictionary(Dictionary<string,int> dict)
{
   dict = new Dictionary<string,int>(); // Just changes the local reference
}

void  ClearDictionary(Dictionary<string,int> dict)
{
   dict.Clear();
}

// When you use this...
Dictionary<string,int> myDictionary = ...; // Set up and fill dictionary

NewDictionary(myDictionary);
// myDictionary is unchanged here, since we made a new copy, but didn't change the original instance

ClearDictionary(myDictionary);
// myDictionary is now empty
dzhpxtsq

dzhpxtsq2#

正如我们已经广泛讨论的那样,效果基本上是相同的。Clear()new都将为您提供一个新的字典,基本上放弃了对字典中对象的引用,如果它们没有根,则可以将它们释放出来进行收集。
从技术上讲,如果您要将字典重新填充到与之前相同的大小,.Clear()将比new更有优势。这是因为它已经在内部调整了大小,以容纳之前的对象数量。创建新的字典将具有一个新的内部哈希表,该哈希表具有默认大小。并且在向其中添加项目时必须重新展开。
我还建议它们传达一个完全不同的意图,当您处理与以前相同的上下文时,您应该在代码中使用.Clear()。创建一个新的Dictionary意味着您将要开始处理与旧Dictionary不同的一些新逻辑,而使用Clear()则表示是的,你真的很想重新设置目前为止你所做的一切。

bq9c1y66

bq9c1y663#

字典.清除()

这将删除字典中的所有键/值对。垃圾收集器将在下一个垃圾收集周期中清除这些项目的内存。MSDN

新建字典()

在内存中创建一个新的Dictionary对象并放弃原来的对象。内存将在下一个垃圾回收周期中被清除。

y1aodyip

y1aodyip4#

我想关键的区别在于如果你调用Dictionary.Clear(),那么所有对那个字典的引用都会被清除;如果你使用new Dictionary(),那么你当时正在处理的引用会被清除(某种意义上),但是所有其他地方的引用不会被清除,因为它们仍然引用旧字典。
希望这段代码能简单地说明这一点:

public void Method()
{
    Dictionary<int, int> d1 = new Dictionary();

    d1.Add(1,1);
    d1.Add(2,3);

    Dictionary<int, int> d2 = d1;

    //this line only 'clears' d1
    d1 = new Dictionary();

    d1.Add(1,1);
    d1.Add(3,5);
    d2.Add(2,2);

    //writes '2' followed by '1'
    Console.WriteLine(d1.Count);
    Console.WriteLine(d2.Count);
}

如果我调用了d1.Clear(),那么d1和d2将保持同步,并且随后的add将添加到两者中,WriteLine调用都将输出'3'。

zbsbpyhn

zbsbpyhn5#

Dictionary.Clear将删除(但不释放)示例中的所有项,而new Dictionary()将创建一个全新的示例,该示例恰好为空。这两者之间可能存在一些微妙的含义。请考虑以下示例。

void Example1()
{
  var collection = new Dictionary<string, string>();
  collection.Add("key1", "value1");
  collection.Add("key2", "value2");
  foreach (var kvp in collection)
  {
    collection = new Dictionary<string, string>();
    Console.WriteLine(kvp);
  }
}

void Example2()
{
  var collection = new Dictionary<string, string>();
  collection.Add("key1", "value1");
  collection.Add("key2", "value2");
  foreach (var kvp in collection)
  {
    collection.Clear();
    Console.WriteLine(kvp);
  }
}

在第一个例子中,原始集合中的所有内容都将被打印出来,这是因为枚举数是在引用变量被重新分配给一个新示例之前从引用变量中创建的。
在第二个示例中,集合在枚举期间被清除,这将导致InvalidOperationException,因为集合被修改。

xfb7svmp

xfb7svmp6#

我相信.Clear()是这样提供的,如果你的字典被公开为只读属性,你将能够删除所有的项目。然而,如果它不是这样公开的,并且你有完全的控制权,那么它可能更容易只是示例化一个新的字典。这两者之间可能也有轻微的性能差异。

col17t5w

col17t5w7#

Dictionary.Clear()(源代码)重置了字典的内部数据结构。内部使用的Entry结构体将符合垃圾收集条件,任何只能通过这些条目访问的键和值也是如此。字典的容量保持不变,尽管自示例化以来可能有所增长。
new Dictionary()分配新对象。新字典的初始容量将是默认值或您指定的值,具体取决于您使用的constructor。如果您使用Clear()方法,则此容量可能与现有字典的容量不同。此容量是否重要将取决于您的环境。
Dictionary.Clear()提供了一种清空字典的方法,该字典中存在对对象的其他引用,而您无法更新这些引用以指向新示例。

yhqotfr8

yhqotfr88#

如果你有几个引用到那个字典,你清除它,你会影响他们所有,就像你创建一个新字典,你只会影响一个新的引用。我猜这取决于影响的范围,你的目标。显然,调用“新”将给予你一个“清除”字典,但你可能会失去其他有用的状态信息。

0sgqnhkj

0sgqnhkj9#

clear将清除字典中的所有项。new Dictionary在内存中创建一个新的字典对象,同时孤立先前的字典,以便垃圾收集器稍后清理。

相关问题