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

New*_*bie 29 .net c# dictionary

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

Ree*_*sey 35

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
Run Code Online (Sandbox Code Playgroud)

  • @divo - 我认为他的意思是参考的副本,而不是对象本身的副本 (2认同)

wom*_*omp 20

如已广泛涵盖的那样,效果基本相同. Clear()并且它们new都会给你一个新的词典,基本上放弃对它内部对象的引用,如果它们没有被引导则释放它们.

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

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

  • 是的.我假设只是一个.Clear()与一个新的Dictionary(). (5认同)
  • >创建一个新的Dictionary将有一个具有默认大小的新内部哈希表 - 不一定,您可以使用构造函数重载来设置初始容量. (4认同)

RSo*_*erg 14

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

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

  • 需要考虑的事项 - 如果您的字典非常大,并且您确定在清除之后您将加载相同的数据 - Dictionary.Clear()不会重置字典的容量这一事实将使它成为现实更加有吸引力. (4认同)

Ant*_*Ant 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);
}
Run Code Online (Sandbox Code Playgroud)

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


Bri*_*eon 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);
  }
}
Run Code Online (Sandbox Code Playgroud)

在第一个示例中,将打印原始集合中的所有内容.这是因为枚举器是在重新分配给新实例之前从引用变量创建的.

在第二个示例中,在枚举期间清除集合,这将导致InvalidOperationException集合被修改.