C# 在 .NET 中使用后将对象设置为 Null/Nothing

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2785/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-07-31 13:32:30  来源:igfitidea点击:

Setting Objects to Null/Nothing after use in .NET

提问by John

Should you set all the objects to null(Nothingin VB.NET) once you have finished with them?

完成后是否应该将所有对象设置为nullNothing在 VB.NET 中)?

I understand that in .NET it is essential to dispose of any instances of objects that implement the IDisposableinterface to release some resources although the object can still be something after it is disposed (hence the isDisposedproperty in forms), so I assume it can still reside in memory or at least in part?

我知道在 .NET 中,必须处理实现IDisposable接口以释放一些资源的任何对象实例,尽管对象在处理后仍然可以是某些东西(因此是isDisposed表单中的属性),所以我认为它仍然可以驻留在记忆中还是至少部分?

I also know that when an object goes out of scope it is then marked for collection ready for the next pass of the garbage collector (although this may take time).

我也知道当一个对象超出范围时,它会被标记为收集准备好垃圾收集器的下一次通过(尽管这可能需要时间)。

So with this in mind will setting it to nullspeed up the system releasing the memory as it does not have to work out that it is no longer in scope and are they any bad side effects?

因此,考虑到这一点,将设置它以null加快系统释放内存的速度,因为它不必确定它不再在范围内并且它们是否有任何不良副作用?

MSDN articles never do this in examples and currently I do this as I cannot see the harm. However I have come across a mixture of opinions so any comments are useful.

MSDN 文章在示例中从未这样做过,目前我这样做是因为我看不到它的危害。但是,我遇到了各种不同的意见,因此任何评论都是有用的。

采纳答案by Kev

Karl is absolutely correct, there is no need to set objects to null after use. If an object implements IDisposable, just make sure you call IDisposable.Dispose()when you're done with that object (wrapped in a try..finally, or, a using()block). But even if you don't remember to call Dispose(), the finaliser method on the object should be calling Dispose()for you.

Karl 是绝对正确的,使用后不需要将对象设置为空。如果对象实现了IDisposable,请确保IDisposable.Dispose()在完成该对象后调用(包装在try..finallyusing()块中)。但即使您不记得调用Dispose(),对象上的终结器方法也应该Dispose()为您调用。

I thought this was a good treatment:

我认为这是一个很好的治疗方法:

Digging into IDisposable

深入研究 IDisposable

and this

和这个

Understanding IDisposable

了解 IDisposable

There isn't any point in trying to second guess the GC and its management strategies because it's self tuning and opaque. There was a good discussion about the inner workings with Jeffrey Richter on Dot Net Rocks here: Jeffrey Richter on the Windows Memory Modeland Richters book CLR via C#chapter 20 has a great treatment:

尝试再次猜测 GC 及其管理策略是没有任何意义的,因为它是自调整的且不透明。在 Dot Net Rocks 上与 Jeffrey Richter 就内部工作进行了很好的讨论:Jeffrey Richter on the Windows Memory Model和 Richters book CLR via C#第 20 章有很好的处理:

回答by GateKiller

Some object suppose the .dispose()method which forces the resource to be removed from memory.

某些对象假设.dispose()强制从内存中删除资源的方法。

回答by Karl Seguin

No don't null objects. You can check out http://codebetter.com/blogs/karlseguin/archive/2008/04/27/foundations-of-programming-pt-7-back-to-basics-memory.aspxfor more information, but setting things to null won't do anything, except dirty your code.

不,不要为空对象。您可以查看http://codebetter.com/blogs/karlseguin/archive/2008/04/27/foundations-of-programming-pt-7-back-to-basics-memory.aspx了解更多信息,但设置空不会做任何事情,除了弄脏你的代码。

回答by Bob

The only time you should set a variable to null is when the variable does not go out of scope and you no longer need the data associated with it. Otherwise there is no need.

您应该将变量设置为 null 的唯一时间是该变量没有超出范围并且您不再需要与其关联的数据。否则没有必要。

回答by Steve Tranby

Also:

还:

using(SomeObject object = new SomeObject()) 
{
  // do stuff with the object
}
// the object will be disposed of

回答by Patrick

There are some cases where it makes sense to null references. For instance, when you're writing a collection--like a priority queue--and by your contract, you shouldn't be keeping those objects alive for the client after the client has removed them from the queue.

在某些情况下,空引用是有意义的。例如,当您正在编写一个集合(如优先级队列)时,根据您的约定,在客户端将它们从队列中删除后,您不应该为客户端保持这些对象的活动状态。

But this sort of thing only matters in long lived collections. If the queue's not going to survive the end of the function it was created in, then it matters a whole lot less.

但这种事情只在长期存在的收藏中重要。如果队列在创建它的函数结束后不会继续存在,那么它的重要性就大大降低了。

On a whole, you really shouldn't bother. Let the compiler and GC do their jobs so you can do yours.

总的来说,你真的不应该打扰。让编译器和 GC 完成它们的工作,这样您就可以完成您的工作。

回答by dbkk

In general, there's no need to null objects after use, but in some cases I find it's a good practice.

一般来说,使用后不需要将对象清空,但在某些情况下,我发现这是一个很好的做法。

If an object implements IDisposable and is stored in a field, I think it's good to null it, just to avoid using the disposed object. The bugs of the following sort can be painful:

如果一个对象实现了 IDisposable 并存储在一个字段中,我认为最好将它设为 null,只是为了避免使用已处理的对象。以下类型的错误可能会很痛苦:

this.myField.Dispose();
// ... at some later time
this.myField.DoSomething();

It's good to null the field after disposing it, and get a NullPtrEx right at the line where the field is used again. Otherwise, you might run into some cryptic bug down the line (depending on exactly what DoSomething does).

处理完该字段后最好将其归零,并在再次使用该字段的行处获得一个 NullPtrEx 。否则,您可能会遇到一些神秘的错误(具体取决于 DoSomething 的作用)。

回答by mbillard

Chances are that your code is not structured tightly enough if you feel the need to nullvariables.

如果您觉得需要null变量,很可能您的代码结构不够紧密。

There are a number of ways to limit the scope of a variable:

有多种方法可以限制变量的作用域:

As mentioned by Steve Tranby

正如史蒂夫·特兰比所提到的

using(SomeObject object = new SomeObject()) 
{
  // do stuff with the object
}
// the object will be disposed of

Similarly, you can simply use curly brackets:

同样,您可以简单地使用大括号:

{
    // Declare the variable and use it
    SomeObject object = new SomeObject()
}
// The variable is no longer available

I find that using curly brackets without any "heading" to really clean out the code and help make it more understandable.

我发现使用没有任何“标题”的大括号可以真正清理代码并帮助使其更易于理解。

回答by Wilka

Another reason to avoid setting objects to null when you are done with them is that it can actually keep them alive for longer.

在处理完对象后避免将对象设置为 null 的另一个原因是,它实际上可以让它们存活更长时间。

e.g.

例如

void foo()
{
    var someType = new SomeType();
    someType.DoSomething();
    // someType is now eligible for garbage collection         

    // ... rest of method not using 'someType' ...
}

will allow the object referred by someType to be GC'd after the call to "DoSomething" but

将允许 someType 引用的对象在调用“DoSomething”后被 GC 处理,但是

void foo()
{
    var someType = new SomeType();
    someType.DoSomething();
    // someType is NOT eligible for garbage collection yet
    // because that variable is used at the end of the method         

    // ... rest of method not using 'someType' ...
    someType = null;
}

may sometimes keep the object alive until the end of the method. The JIT will usually optimized away the assignment to null, so both bits of code end up being the same.

有时可能会使对象保持活动状态直到方法结束。在JIT通常会优化掉分配给空,所以代码端的向上是相同的两个位。

回答by Scott Dorman

Take a look at this article as well: http://www.codeproject.com/KB/cs/idisposable.aspx

也看看这篇文章:http: //www.codeproject.com/KB/cs/idisposable.aspx

For the most part, setting an object to null has no effect. The only time you should be sure to do so is if you are working with a "large object", which is one larger than 84K in size (such as bitmaps).

在大多数情况下,将对象设置为 null 不起作用。您应该确保这样做的唯一时间是您正在处理一个“大对象”,它的大小大于 84K(例如位图)。