Dictionary.Clear和新词典()之间的差异
-
05-07-2019 - |
题
C#中 Dictionary.Clear
和 new Dictionary()
之间的主要区别是什么?在哪些情况下推荐哪一个?
解决方案
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
其他提示
正如已广泛报道的那样,效果基本相同。 Clear()
和 new
都会给你一个新的词典,基本上放弃对它里面的对象的引用,如果它们没有被引用就会释放它们。
从技术上讲,如果您要将字典重新填充到与以前相同的大小, .Clear()
将优于 new
。这是因为它已经在内部调整大小以保存之前的对象数量。创建一个新的Dictionary会有一个具有默认大小的新内部哈希表,并且在向其添加项目时必须重新展开。
我还建议他们传达完全不同的意图,当你处理与以前相同的上下文时,你应该在你的代码中使用 .Clear()
。创建一个新词典意味着你将要开始处理一些与旧词典不同的新逻辑,而使用 Clear()
表示是的,你真的想重置你所有的东西到目前为止完成了它。
<强> Dictionary.Clear()强>结果 这将删除Dictionary中的所有键/值对。垃圾收集器将在下一个垃圾收集周期中清除这些项目的内存。 MSDN
新词典()
在内存中创建一个新的Dictionary对象并放弃原始对象。在下一个垃圾收集周期中,内存将被清除。
我认为关键的区别在于,如果你调用 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'。
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
,因为集合已被修改。
我相信.Clear()已经提供,因此如果您的Dictionary作为只读属性公开,您将能够删除所有项目。但是,如果它没有以这种方式暴露,并且您具有完全控制权,则可能更容易实例化新的词典。两者之间可能存在轻微的性能差异。
如果您有多个对该词典的引用并清除它,则会影响它们,就像您创建一个新词典一样,您只会影响一个新词典。我想这取决于你所瞄准的影响范围。显然是对“新”的呼唤会给你一个“清除”的字典,但你可能会丢失其他有用的状态信息。
Dictionary.clear将逐出你词典中的所有项目。 new Dictionary在内存中创建一个新的字典对象,同时将以前的Dictionary用于垃圾收集器,以便以后清理。