Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在.NET中使用后将对象设置为Null/Nothing_C#_.net_Vb.net_Memory Management_Null - Fatal编程技术网

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

C# 在.NET中使用后将对象设置为Null/Nothing,c#,.net,vb.net,memory-management,null,C#,.net,Vb.net,Memory Management,Null,完成所有对象后,是否应将它们设置为null(Nothing,在VB.NET中) 我知道在.NET中,必须处理实现IDisposable接口的对象的任何实例,以释放一些资源,尽管对象在被处理后仍然可以是某种东西(因此isDisposed属性在表单中),所以我假设它仍然可以驻留在内存中,或者至少部分驻留在内存中 我还知道,当一个对象超出作用域时,它会被标记为准备收集,以便下一次通过垃圾收集器(尽管这可能需要时间) 因此,考虑到这一点,将其设置为null会加快系统释放内存的速度,因为它不必计算出它不再

完成所有对象后,是否应将它们设置为
null
Nothing
,在VB.NET中)

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

我还知道,当一个对象超出作用域时,它会被标记为准备收集,以便下一次通过垃圾收集器(尽管这可能需要时间)

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

MSDN文章从来没有在示例中这样做过,目前我做不到这一点
看到危害了吧。然而,我遇到了各种各样的观点,因此任何注释都是有用的。

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

否不允许对象为空。您可以查看更多信息,但将内容设置为null不会起任何作用,只会弄脏您的代码。

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

另外:

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

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

但这类东西只在长寿命的收藏品中起作用。如果队列不能在创建它的函数结束后继续存在,那么它就不那么重要了


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

Karl是绝对正确的,使用后不需要将对象设置为null。如果一个对象实现了
IDisposable
,只需确保在处理完该对象后调用
IDisposable.Dispose()
(包装在
中,最后尝试
或者
使用()
块)。但是,即使您不记得调用
Dispose()
,对象上的finalizer方法也应该为您调用
Dispose()

我认为这是一种很好的治疗:

还有这个

试图对GC及其管理策略进行二次猜测是没有任何意义的,因为它是自调优和不透明的。与Jeffrey Richter在Dot Net Rocks上就内部工作进行了很好的讨论:以及
Richters的书第20章有一个很好的处理方法:

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

如果一个对象实现IDisposable并存储在一个字段中,我认为最好将其设为null,以避免使用disposed对象。以下类型的错误可能会令人痛苦:

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

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

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

有许多方法可以限制变量的范围:

如Steve Tranby所述

using(SomeObject object = new SomeObject()) 
{
  // do stuff with the object
}
// the object will be disposed of
类似地,您可以简单地使用花括号:

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

我发现使用不带任何“标题”的花括号可以真正清理代码并使其更易于理解。

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

e、 g

将允许在调用“DoSomething”后对someType引用的对象进行GC'd,但是


有时可能会使对象保持活动状态,直到方法结束。因此,这两个代码位最终都是相同的。

也可以看看这篇文章:

在大多数情况下,将对象设置为null没有效果。只有在使用大于84K的“大对象”(如位图)时,才应确保这样做。

这种“使用后无需将对象设置为空”并不完全准确。在处理变量后,有时需要将其设为NULL

是的,当您完成操作时,您应该始终调用
.Dispose()
.Close()
。无论是文件句柄、数据库连接还是一次性对象

与此不同的是懒散的实际模式

假设我拥有并实例化了
A类
ObjA
<代码>A类
有一个名为
PropB
的公共属性,属于
B类

在内部,
PropB
使用私有变量
\u B
并默认为null。当使用
PropB.Get()
时,它会检查
\u PropB
是否为空,如果为空,则会打开将
B
实例化为
\u PropB
所需的资源。然后返回
\u PropB

根据我的经验,这是一个非常有用的技巧

如果您以某种方式重置或更改A,而
\u PropB
的内容是
A
以前的值的子项,则需要对其进行处理并清空
\u PropB
,以便LazyLoad可以在代码需要时重置以获取正确的值

如果您只执行
\u PropB.Dispose()
,并且在期望LazyLoad的null检查成功后不久,它将不会为null,您将看到过时的数据。实际上,您必须在
Dispose()
ju之后将其置空
void foo()
{
    var someType = new SomeType();
    someType.DoSomething();
    // someType is now eligible for garbage collection         

    // ... rest of method not using 'someType' ...
}
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;
}
private void Reset()
{
    if(_dataset != null)
    {
       _dataset.Dispose();
       _dataset = null;
    }
    //..More such member variables like oracle connection etc. _oraConnection
 }