C# 弱引用和一次性对象

C# 弱引用和一次性对象,c#,garbage-collection,weak-references,C#,Garbage Collection,Weak References,在C#中,可以创建对对象的弱引用,如下所述: 在.net中,一些类还实现IDisposable接口。执行调用此接口的Dispose方法以手动处置当前持有的任何托管或非托管资源。例如,位图对象或类 如果我将实现IDisposable的对象分配给弱引用,那么如果弱引用收集该对象,将调用Dispose吗?否。像这样简单;) GC从不调用Dispose。Dispose必须由用户代码调用。否。请检查此测试: class Program { static void Main(string[

在C#中,可以创建对对象的弱引用,如下所述:

在.net中,一些类还实现IDisposable接口。执行调用此接口的Dispose方法以手动处置当前持有的任何托管或非托管资源。例如,位图对象或类


如果我将实现IDisposable的对象分配给弱引用,那么如果弱引用收集该对象,将调用Dispose吗?

否。像这样简单;)

GC从不调用Dispose。Dispose必须由用户代码调用。

否。请检查此测试:

class Program {
        static void Main(string[] args) {
            Test test = new Test();
            Console.WriteLine(test.Disposable == null);
            GC.Collect();
            Console.WriteLine(test.Disposable == null);
            Console.ReadLine();
        }
    }

    public class Test {
        private WeakReference disposable = new WeakReference(new WeakDisposable());
        public WeakDisposable Disposable {
            get { return disposable.Target as WeakDisposable; }
        }
    }

    public class WeakDisposable : IDisposable {
        ~WeakDisposable() {
            Console.WriteLine("Destructor");
        }
        public void Dispose() {
            Console.WriteLine("Dispose");
        }
    }
输出为:

False
True
Destructor

正如您所看到的,执行从未命中
Dispose
方法。

一般来说,答案确实是否定的

但是,一个正确实现的类使用实现了
IDisposable
(希望所有.NET类都能这样做)。还将实现当对象被垃圾收集时调用的终结器,在终结器内部,它将调用
Dispose
。因此,对于
IDisposable
的所有正确实现,将调用
Dispose
方法


(注意:Fernando的反例没有正确实现
IDisposable

收集对象的“Weakreference”是什么意思?它只是一个弱引用,即它指向的对象可能被垃圾收集器收集。在本例中,您所知道的关于垃圾收集器的所有信息都适用于……正如Frank所说,垃圾收集器只会收集对象。这反过来会触发终结器(如果有)。不过,Dispose方法将永远不会触发。如果将中的
RefCountDisposable
替换为
WeakReference
,您的设计可能会更好。实际上,“标准”终结器仅调用
Dispose(bool)
<代码>Dispose()未调用,因此任何依赖于托管代码的清理(例如,刷新底层文件流)都无法完成。@StephenClearly Per模式Dispose(bool)由终结器和Dispose调用,两者均未实现该工作。因为从未调用Dispose。。如果类型具有任何托管资源,则必须正确实现终结器(或始终正确处置)。