.NET中对象的生命周期是什么?
据我所知,它是:
- 对象创建 - 调用构造函数(如果存在)
- 使用方法/属性/字段
- 对象销毁 - 调用Dispose(如果存在)
- 垃圾回收器在某个时刻调用析构函数
Dispose方法不会自动调用,你需要手动调用它,或者使用using块,例如:
using(Stream s = File.OpenRead(@"c:\temp\somefile.txt"))
// Do something with s
如果存在终结器,GC才会调用它。拥有终结器会导致您的类在2个步骤中被收集;首先将对象放入终结器队列,然后调用终结器并收集对象。没有终结器的对象会直接被收集。
准则是Dispose处理托管和非托管资源,而终结器仅清理非托管资源。当Dispose方法释放了非托管资源时,可以调用GC.SuppressFinalize以避免对象长时间存活并进入终结器队列。请参见MSDN以获取正确的dispose模式示例。
就像一个边界情况一样...你可以在不使用构造函数的情况下创建对象:
class Foo {
public Foo() {
message += "; ctor";
}
string message = "init";
public string Message { get { return message; } }
}
static class Program {
static void Main() {
Foo foo = new Foo();
Console.WriteLine(foo.Message); // "init; ctor"
Foo bar = (Foo)System.Runtime.Serialization.FormatterServices
.GetSafeUninitializedObject(typeof(Foo));
Console.WriteLine(bar.Message); // null
}
}
/*********************************
* Author: Theofanis Pantelides *
* Date: 23 Jun 2009 *
*********************************/
using System;
using System.IO;
public class MyClass : IDisposable
{
String oFile;
Stream oStream;
public MyClass(String _File)
{
oStream = File.OpenRead(oFile = _File);
// Initialize
}
~MyClass()
{
this.Dispose();
// Destruct
}
public void doSomething()
{
// do Whatever it is you are trying to do
}
#region IDisposable Members
/// <summary>
/// Dispose all resources used by instance of class
/// and update Garbage Collector information
/// </summary>
public void Dispose()
{
if (oStream != null)
{
oStream.Dispose(); // Dispose using built in functions
GC.SuppressFinalize(oStream); // No need for Garbage Collector
}
oStream = null; // Nullify it.
}
#endregion
}
使用方法:
using(MyClass mc = new MyClass(@"c:\temp\somefile.txt"))
{
mc.doSomething();
}
你甚至可以两次使用相同的声明,因为它在“using”之外不存在。
using(MyClass mc = new MyClass(@"c:\temp\somefile.txt"))
{
mc.doSomething();
}
using(MyClass mc = new MyClass(@"c:\temp\somefile.txt"))
{
mc.doSomething();
}
对象的生命周期
创建对象:使用new关键字实例化新对象。
销毁对象:使用销毁来回收该对象使用的任何资源。
CLR处理托管对象使用的内存释放;但是,如果您使用非托管对象,则可能需要手动释放这些项目使用的内存。
0) 如果对象中存在静态构造函数,则在首次创建或引用该类型的对象时调用它。
Finalize
。Dispose
的工作很容易出错,通常不值得花费时间。
object
通常用作同步锁,但它从不访问任何成员。 - Marc Gravell