Dictionary.Clear和新词典()之间的差异

时间:2009-09-09 15:53:51

标签: c# .net dictionary

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

8 个答案:

答案 0 :(得分:33)

Dictionary.Clear()将删除字典中的所有KeyValue对。执行new Dictionary()将创建字典的新实例。

如果且仅当旧版本的字典没有被另一个引用植根时,创建一个新字典将构成整个字典,并且它的内容(它们没有在其他地方生根)可供GC清理。 / p>

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

答案 1 :(得分:20)

正如已广泛报道的那样,效果基本相同。 Clear()new都会给你一个新的词典,基本上放弃了对它内部对象的引用,如果它们没有被引用就会释放它们。

从技术上讲,如果您要将字典重新填充到与以前相同的大小,.Clear()将优于new。这是因为它已经在内部调整大小以保存之前的对象数量。创建一个新的Dictionary会有一个具有默认大小的新内部哈希表,并且在向其添加项目时必须重新展开。

我还建议他们传达完全不同的意图,当您处理与以前相同的上下文时,您应该在代码中使用.Clear()。创建一个新词典意味着你将要开始处理一些与旧词典不同的新逻辑,而使用Clear()表示是的,你真的想重置你迄今为止所做的一切

答案 2 :(得分:14)

<强> Dictionary.Clear()
这将删除Dictionary中的所有键/值对。垃圾收集器将在下一个垃圾收集周期中清除这些项目的内存。 MSDN

新词典()
在内存中创建一个新的Dictionary对象并放弃原始对象。在下一个垃圾收集周期中,内存将被清除。

答案 3 :(得分:6)

我认为关键的区别在于,如果你调用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将保持同步,后续添加将添加到两者。 WriteLine调用都会输出'3'。

答案 4 :(得分:5)

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,因为集合已被修改。

答案 5 :(得分:3)

我相信.Clear()已经提供,因此如果您的Dictionary作为只读属性公开,您将能够删除所有项目。但是,如果它没有以这种方式暴露,并且您具有完全控制权,则可能更容易实例化新的词典。两者之间可能存在轻微的性能差异。

答案 6 :(得分:1)

如果您有多个对该词典的引用并清除它,则会影响它们,就像您创建新词典一样,您只会影响一个新词典。我想这取决于你所瞄准的影响范围。显然,对“new”的调用将为您提供“已清除”字典,但您可能会丢失其他有用的状态信息。

答案 7 :(得分:0)

Dictionary.clear将逐出你词典中的所有项目。 new Dictionary在内存中创建一个新的字典对象,同时将以前的Dictionary用于垃圾收集器,以便以后清理。