C#:应该将对象变量赋值为null吗?

Cra*_*ton 45 c# null garbage-collection

在C#中,null如果你已经完成使用它,是否有必要分配一个对象变量,即使它会超出范围?

Dan*_*olo 39

不,这实际上可能是危险的并且容易出错(考虑以后有人可能会尝试使用它,而不是意识到它已被设置为null).如果将逻辑原因设置为null,则仅将某些内容设置为null.


Vin*_*ayC 27

更重要的是IMO是在实现IDisposable的对象上调用Dispose.

除此之外,为引用变量赋值null只意味着您明确指示范围的结束 - 大多数时候,它只提前几条指令(例如,方法体中的局部变量) - 随着编译器/ JIT优化的时代,它的很可能运行时会做同样的事情,所以你真的不能从中获取任何东西.在少数情况下,例如静态变量等(其范围是应用程序级别),如果已完成使用它,则应将变量赋值为null,以便对象将被垃圾收集.

  • 此幻灯片演示文稿http://download.microsoft.com/download/e/2/1/e216b4ce-1417-41af-863d-ec15f2d31b59/DEV490.ppt,向前滑动30,显示JIT/GC一起执行的操作.这意味着空分配特别没有意义. (6认同)
  • 你是说垃圾收集器会查看变量是否为null来决定是否进行垃圾收集?我认为这只是它是否还活着/范围内. (2认同)

Kob*_*obi 25

在把车推到湖边之前你应该把车关掉吗?
不.这是一个常见的错误,但它没有任何区别.您没有将对象设置为null,只是对它的一个引用 - 对象仍然在内存中,并且仍然必须由垃圾收集器收集.


use*_*635 18

大多数这些回答都有正确的答案,但出于错误的原因.

如果它是局部变量,则变量将在方法结束时从堆栈中掉落,因此它指向的对象将少一个引用.如果该变量是对象的唯一引用,则该对象可用于GC.

如果你将变量设置为null(并且许多人被教导在方法结束时这样做)那么你实际上可以最终延长对象留在内存中的时间,因为CLR会认为对象不能收集到方法结束,因为它看到了对象的代码引用.但是,如果省略null设置,则CLR可以确定在代码中的某个点之后不再显示对象,并且即使该方法尚未完成,GC也可以收集该对象.


Jon*_*nna 12

分配给null通常是个坏主意:

  1. 从概念上讲,这是毫无意义的.
  2. 对于许多变量,您可以对null进行足够的额外分配,这会明显增加方法的大小.某些东西的源代码越长,读取它的精力就越多(即使其中大部分只是可以过滤掉的东西)并且更容易发现错误.只有当这样做使代码更容易理解时,才使代码更加冗长.
  3. 您的空作业可能不会被优化掉.在这种情况下,编译的代码可能不会进行真正的释放,直到它实际到达那个空赋值,而在大多数情况下,一旦变量除了超出范围(有时甚至在之前)之外什么都不做可以解除分配.因此,您可以对性能产生非常小的影响.

我唯一一次将一些东西分配给null来"清除"一个不再使用的变量,而不是因为null实际上是一个我明确想要分配的值,这是两种可能的情况之一:

  1. 它是一个可能长寿的对象的成员,将不再被该对象使用,并且具有相当大的尺寸.这里赋值为null是一种优化.
  2. 它是一个可能长寿的对象的成员,将不再被该对象使用,因此已被释放以释放其资源.这里赋值为null是一个安全问题,因为它可以更容易地找到一个意外使用空对象的情况,而不是一个意外使用已处置对象的情况.

这些情况都不适用于局部变量,仅适用于成员,两者都很少见.


Guf*_*ffa 5

否。当涉及局部变量时,无论是否有对象引用都没有任何区别,重要的是是否使用引用。

在代码中添加额外的null分配不会对性能造成太大影响,也完全不会影响内存管理,但是会在代码中添加无用的语句,从而降低了可读性。

垃圾收集器知道代码中最后一次使用引用的时间,因此它可以在不再需要该对象时收集该对象。

例:

{
  // Create an object
  StringBuilder b = new StringBuilder();
  b.Append("asdf");
  // Here is the last use of the object:
  string x = b.ToString();
  // From this point the object can be collected whenever the GC feels like it
  // If you assign a null reference to the variable here is irrelevant
  b = null;
}
Run Code Online (Sandbox Code Playgroud)