C# Dictionary.Clear和new Dictionary()之间的差异

C# Dictionary.Clear和new Dictionary()之间的差异,c#,.net,dictionary,C#,.net,Dictionary,C语言中的字典.Clear和新字典()?对于哪些情况,建议使用哪一个?字典。清除将删除字典中的所有项。new Dictionary在内存中创建一个新的Dictionary对象,同时孤立以前的字典,以便垃圾收集器稍后清理。Dictionary.Clear() 这将删除字典中的所有键/值对。垃圾收集器将在下一个垃圾收集周期中清除这些项的内存 新词典() 在内存中创建新的Dictionary对象并放弃原始对象。内存将在下一个垃圾收集周期中被清除。Dictionary.Clear()将删除Diction

C语言中的
字典.Clear
新字典()?对于哪些情况,建议使用哪一个?

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

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

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

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

如果(且仅当)词典的旧版本没有被另一个引用作为根目录,则创建新词典将使整个词典及其内容(没有在其他地方作为根目录)可供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
void NewDictionary(Dictionary dict)
{
dict=new Dictionary();//只更改本地引用
}
无效ClearDictionary(Dictionary dict)
{
格言(Clear);
}
//当你使用这个。。。
字典myDictionary=…;//建立并填写字典
新字典(myDictionary);
//myDictionary在这里保持不变,因为我们制作了一个新的副本,但没有更改原始实例
ClearDictionary(myDictionary);
//我的字典现在是空的

我想关键的区别在于,如果调用
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);
}
public void方法()
{
字典d1=新字典();
d1.添加(1,1);
d1.加入(2,3);
字典d2=d1;
//此行仅“清除”d1
d1=新字典();
d1.添加(1,1);
d1.添加(3,5);
d2.加入(2,2);
//写入“2”,后跟“1”
控制台写入线(d1计数);
控制台写入线(d2计数);
}

如果我调用了
d1.Clear()
,那么d1和d2将保持同步,随后的添加将同时添加到两者。WriteLine调用将同时具有输出“3”。

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

字典。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);
  }
}
void Example1()
{
var collection=newdictionary();
集合。添加(“键1”、“值1”);
集合。添加(“键2”、“值2”);
foreach(集合中的var kvp)
{
集合=新字典();
控制台写入线(kvp);
}
}
无效示例2()
{
var collection=newdictionary();
集合。添加(“键1”、“值1”);
集合。添加(“键2”、“值2”);
foreach(集合中的var kvp)
{
collection.Clear();
控制台写入线(kvp);
}
}
在第一个示例中,将打印原始集合中的所有内容。这是因为枚举数是在重新分配给新实例之前从引用变量创建的


在第二个示例中,在枚举过程中清除集合,这将导致
InvalidOperationException
,因为集合已被修改。

正如广泛讨论的那样,效果基本相同
Clear()
new
都会为您提供一个全新的字典,基本上放弃了对其中对象的引用,如果这些对象没有根,则可以自由地收集它们

从技术上讲,
.Clear()
new
更有优势,前提是您要将字典重新填充到与以前相同的大小。这是因为它已经在内部调整了大小,以容纳之前在其中的对象数量。创建一个新字典将有一个默认大小的新内部哈希表,并且在向其中添加项时必须重新扩展该哈希表

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

我相信。Clear()提供的,以便如果您的字典作为只读属性公开,您将能够删除所有项。然而,如果它不是以这种方式公开的,并且您拥有完全的控制权,那么只实例化一个新字典可能会更容易。两者的性能也可能略有不同。

我们能比“大多数”做得更好吗