当代码块结束时,var类型会发生什么?

本文关键字:什么 类型 var 代码 结束 | 更新日期: 2023-09-27 18:01:45

这两个代码示例的区别是什么?

  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);
    }

当代码块结束时,var类型会发生什么?

你实际上并不是在比较相似的东西,因为所有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

无。

出于可读性和未来维护的考虑,请使用第二个。它显然更容易理解,而且由于c#和CLR的设计,第一个示例中的大部分代码都是不必要的。

我会试着解释我的意思。您不需要清除或将任何对局部变量的引用设置为空(垃圾收集器将为您完成此操作)。您只需要对类级字段执行此操作,通常甚至不需要这样做(同样,当您的类超出作用域时,垃圾收集器将收集它们)。

考虑更多地关注对象是一次性的概念,不要担心内存使用/垃圾收集方面的问题。清空列表或将列表的引用设置为null实际上不会回收内存;内存仍然被分配,直到垃圾收集器在将来某个不确定的时间回收它。

有强制垃圾收集的方法,但如果需要这样做,通常意味着您做错了什么。有些人会说,如果你需要这么详细地考虑内存问题,那么。net可能不是你的问题领域的正确选择。

同样,使用var或显式指定类型没有任何区别。

唯一值得一提的区别是,当您手动清除列表时,您释放了对该对象的引用。在另一个版本中,列表将在垃圾收集器处理期间清除引用,这可能随时发生。

这是一个很小的区别,因为释放的引用只会在GC收集时自己被处理。

这取决于你如何处理"DoStuff"。在第二个示例中,如果创建对该列表的另一个引用,垃圾收集器将不会清除它们。所以第一个例子保证列表被清除,在第二个例子中它依赖于"DoStuff"。

我将使用以下代码:

DoStuff(CreateList(nCount), CreateList(nCount + 1));