C# 将对象设置为null是否确定地处理对象?

C# 将对象设置为null是否确定地处理对象?,c#,C#,我有一个奇怪的问题,我找不到一个明确的答案,即使有线程围绕着同一个问题 问题:如果我将一个对象设置为null,是否会导致dispose方法(已实现)被确定地调用?例如,在下面的代码中,通过将PricinGenEnvironment对象设置为null,Dispose会立即被调用吗?我知道如果没有调用Dispose,PricinGenEnvironment对象的终结器将在某个时候启动 代码: 谢谢, -Mike没有*方法确定垃圾收集器何时将收集对象并调用其终结器(并且,按照代码中的逻辑,Dispos

我有一个奇怪的问题,我找不到一个明确的答案,即使有线程围绕着同一个问题

问题:如果我将一个对象设置为null,是否会导致dispose方法(已实现)被确定地调用?例如,在下面的代码中,通过将PricinGenEnvironment对象设置为null,Dispose会立即被调用吗?我知道如果没有调用Dispose,PricinGenEnvironment对象的终结器将在某个时候启动

代码:

谢谢,
-Mike

没有*方法确定垃圾收集器何时将收集对象并调用其终结器(并且,按照代码中的逻辑,
Dispose
方法)。 下面是一个很好的示例,说明了垃圾收集的不可预测性:

甚至当GC启动并收集第一代对象时,
PricingEnvironment
的实例也会在第一次收集后继续存在,并被放在最终确定队列中

您应该通过显式调用
dispose
或使用
using
块来确定地处置对象


*实际上,您可以使用GC.Collect()强制它,但您不应该这样做。

虽然计算机根据定义是确定性的,但当分配的内存被释放时,完全取决于语言实现的垃圾收集器。将其设置为null会减少分配内存的引用计数,但在任何情况下,当到达作用域结束时都会发生这种情况。

不,不会

这样做:

    public void Dispose()
    {
        // check if object has IDisposble implemented
        IDisposable disposePricing = pricingEnvironment as IDisposable;
        if (disposePricing!=null)
        {
            disposePricing.Dispose();
        }
    }

读一读

我猜你把垃圾处理和垃圾收集混淆了

Dispose释放非托管资源(数据库连接或文件句柄)

GC通过不再使用的对象释放占用的内存

Disposing是确定性的,因为它在调用Dispose时运行(无论是在
中使用
块显式还是隐式)

垃圾收集本质上是不确定的。它在合适的时候运行。只有这样,它才能释放内存引用。 例如,如果GC运行的生成级别与对象当前所在的生成级别不同,则不会收集该对象


您可以通过调用
GC.Collect()
显式运行GC,但请自问是否应该对GC进行二次猜测。

在.NET中不能保证会调用终结器。垃圾收集器可能根本不调用它(例如,因为垃圾收集器根本不需要释放内存),并且在一个终结器抛出异常的情况下,其他终结器将不会执行(请参阅)。如果对对象调用
SuppressFinalizer
,甚至可以抑制终结器

话虽如此,当然也不能保证立即调用终结器(它可能会在很久以后调用,或者根本不调用)

您应该显式调用
Dispose
,或者使用
using
-语句使用
,以便正确地处理对象。作为安全网,您仍然可以从终结器调用
Dispose
。事实上,这也是中的示例所展示的最佳实践

关于这个话题,雷蒙德·陈(Raymond Chen)的文章读得很好:


作为旁注,我想说的是,如果你处理的对象相对较小,你可以让垃圾收集器独自完成他的工作。我不知道这是否是一个好的实践,但我几乎只使用
dispose()
关于文件或数据库连接…这并不是你的问题的重复,而是关于设置Null vs Dispose的一个非常好的答案-@Bartdude:好的实践表明,每当类实现IDisposable时,你都应该调用trhe Disposemethod@LuisFilipe>感谢您的见解:-)从现在起,我将在我的编码中制定规则!
    public void Dispose()
    {
        // check if object has IDisposble implemented
        IDisposable disposePricing = pricingEnvironment as IDisposable;
        if (disposePricing!=null)
        {
            disposePricing.Dispose();
        }
    }