这两个代码示例有什么区别?
public Test(int x)
{
List<int> list= new List<int>();
List<int> list1 = new List<int>();
list= CreateList(x);
list1 = CreateList(x + 1);
DoStuff(list, list1);
list.Clear();
list = null;
list1.Clear();
list1 = null;
}
这是代码的方式吗?
public Test(int nCount)
{
var list = CreateList(nCount);
var list1 = CreateList(nCount + 1);
DoStuff(list, list1);
}
答案 0 :(得分:3)
你实际上并没有比较像是喜欢所有var
意味着“让编译器决定它是什么类型”。它将编译为相同的代码(假设CreateList
返回List<int>
)。因此,虽然您的代码在功能上完全相同,但您在第一个示例中正在执行额外的工作,而您在第二个示例中没有复制。
在第一种情况下,您不必要地创建列表,因为从CreateList(x)
返回列表的行为将覆盖您刚刚创建的列表。一个更准确的问题是要求这两者之间的区别:
public Test(int x)
{
List<int> list= CreateList(x);
List<int> list1 = CreateList(x + 1);
DoStuff(list, list1);
list.Clear();
list = null;
list1.Clear();
list1 = null;
}
和
public Test(int nCount)
{
var list = CreateList(nCount);
var list1 = CreateList(nCount + 1);
DoStuff(list, list1);
}
在这两种情况下,由于列表超出范围,因此它们将被标记为有资格进行垃圾收集。您无需拨打Clear()
或将变量设置为null
。
答案 1 :(得分:2)
没有
为了便于阅读以及将来的维护原因,请使用第二个。它显然更容易理解,并且由于C#和CLR的设计,第一个示例中的大部分代码都不是必需的。
我会试着解释一下我的意思。您不需要清除或设置为null对本地变量的任何引用(垃圾收集器将为您执行此操作)。您只需要为类级别字段执行此操作,并且通常不会这样做(同样,当您的类超出范围时,垃圾收集器将收集它们。)
考虑更多地关注对象disposable的概念,并且不要担心内存使用/垃圾收集方面。清空列表或将列表引用设置为null实际上不会回收内存;仍然会分配内存,直到垃圾收集器在将来某个不确定的时间收回它。
有办法强制垃圾收集,但通常这意味着如果你需要走得那么远,你做错了什么。有人会说如果你需要担心内存如此详细,那么.NET可能不是你问题领域的正确语言选择。
此外,使用var
或明确指定类型也没有任何区别。
答案 2 :(得分:0)
值得一提的唯一区别是,当您手动清除列表时,您将在此时释放对对象的引用。在另一个版本中,列表将清除垃圾收集器处理过程中的引用,这些引用可以随时发生。
这是一个微小的差别,因为发布的引用只会在GC收集时自行处理。
答案 3 :(得分:0)
这取决于你对“DoStuff”的处理方式。如果您创建对列表的另一个引用,则垃圾收集器将不会在第二个示例中清除它们。所以第一个例子保证列表被清除,第二个例子依赖于“DoStuff”。
我会使用以下代码:
DoStuff(CreateList(nCount), CreateList(nCount + 1));