C# - 更改非托管对象的引用

C# - Changing the reference of a unmanaged object

所以假设创建一个对非托管对象的引用...

RandomObject x;

然后我将该引用分配给一个非托管对象。

x = new RandomObject(argX, argY);

但后来我决定让 x 引用该对象的另一个实例:

x = new RandomObject(argZ, argV);

这种情况下发生了什么?当我将 x 重新分配给非托管对象的不同实例时,"new RandomObject(argX, argY)" 是否被处置?还是我必须在重新分配之前自己处理它?我问的是这个对象的生命周期。

在C#中,垃圾收集器将管理所有对象并释放不再有任何引用的任何对象的内存。

使用你的例子:

RandomObject x;
// A RandomObject reference is defined.

x = new RandomObject(argX, argY);
// Memory is allocated, a new RandomObject object is created in that memory location, 
// and "x" references that new object.

x = new RandomObject(argZ, argV);
// Memory is allocated, a new RandomObject object is created in that memory location,
// and "x" references that new object. The first RandomObject object no longer has 
// any references to it and will eventually be cleaned up by the garbage collector.

非托管资源

尽管 C# 中的所有对象都是托管的,但仍有 "unmanaged resources" 打开的文件或打开的连接。当具有非托管资源的对象超出范围时,它将被垃圾收集,但垃圾收集器不会释放那些非托管资源。这些对象通常实现 IDisposable 允许您在资源被清理之前处理它。

例如StreamWriterclass中有一个非托管资源,它打开一个文件并写入它。

这是一个未能释放非托管资源的示例:

// This will write "hello1" to a file called "test.txt".
System.IO.StreamWriter sw1 = new System.IO.StreamWriter("test.txt");
sw1.WriteLine("hello1");

// This will throw a System.IO.IOException because "test.txt" is still locked by 
// the first StreamWriter.
System.IO.StreamWriter sw2 = new System.IO.StreamWriter("test.txt");
sw2.WriteLine("hello2");

要正确释放文件,您必须执行以下操作:

// This will write "hello1" to a file called "test.txt" and then release "test.txt".
System.IO.StreamWriter sw1 = new System.IO.StreamWriter("test.txt");
sw1.WriteLine("hello1");
sw1.Dispose();

// This will write "hello2" to a file called "test.txt" and then release "test.txt".
System.IO.StreamWriter sw2 = new System.IO.StreamWriter("test.txt");
sw2.WriteLine("hello2");
sw2.Dispose();

幸运的是,实现 IDisposable 的对象可以在 using 语句中创建,然后当它超出范围时 Dispose() 将自动对其调用。 这比手动调用 Dispose(如前面的示例)要好,因为如果在 using 块中有任何意外的退出点,您可以放心,您的资源已被释放。

using (System.IO.StreamWriter sw1 = new System.IO.StreamWriter("test.txt"))
{
  sw1.WriteLine("hello1");
}

using (System.IO.StreamWriter sw2 = new System.IO.StreamWriter("test.txt"))
{
  sw2.WriteLine("hello2");
}