我是C#的初学者,我不知道为什么这个方法不起作用,我只想通过调用Dispose()
方法将该对象设置为null。
为什么这不可能呢?
class MyClass:IDisposable
{
public void Dispose()
{
this = null;
}
}
我是C#的初学者,我不知道为什么这个方法不起作用,我只想通过调用Dispose()
方法将该对象设置为null。
为什么这不可能呢?
class MyClass:IDisposable
{
public void Dispose()
{
this = null;
}
}
Dispose
方法的目的不是为了清理该类,而是为了清理该类所持有的可处理对象,以便可以通过垃圾回收器正常地进行处理。
我建议您进一步阅读关于Dispose
模式和如何在C#中实现它的内容。
有点吹毛求疵: Dispose
方法不是析构函数,也不是终结器。
class MyClass : IDisposable {
public void Dispose() { }
}
using (MyClass instance = new MyClass())
{
} // instance.Dispose() is called here at the end of the block.
Dispose()
的语句,您可以利用它来处理重要的资源,例如文件和数据库连接。例如,所有Stream
类(如FileStream
等)都实现了IDisposable
,因为保留文件打开状态是不好的做法。相反,您可以将所有访问包装在using
块中,然后您可以确保FileStream.Dispose
会关闭文件。请考虑以下示例:using (FileStream myFile = File.OpenRead("..."))
{
// Read the content of the file.
} // The file is guaranteed to be closed here. Cool!
这比像这样做更整洁:
FileStream stream = File.OpenRead(" ... ");
stream.Close(); // Yes, you closed it manually, but it's error prone. What if you forget to do this?
System.GC
类)实际销毁对象并清理其内存时。考虑以下内容:public class MyClass {
// This method, the 'Finalizer' will be called when the class is destroyed.
// The 'finalizer' is essentially just the name of the class with a '~' in front.
~MyClass() {
Console.WriteLine("Destroyed!");
}
}
public class Program {
public static void Main() {
MyClass referenceHeld = new MyClass(); // Reference held
new MyClass(); // No reference held on this class
WeakReference sameAsNoReference = new WeakReference(new MyClass()); // Equivalent to no reference.
System.GC.Collect(); // Force the garbage collector to collect
Console.ReadLine();
}
}
Main
函数中创建的MyClass
实例中有两个未被引用指向(WeakReference
本质上与没有引用相同)。当我们调用GC.Collect()
时,垃圾回收器运行并清理引用。GC.Collect
。当然,你可以进行试验和教育,但大多数人会告诉你,垃圾回收器自己很好地保持了清洁。在你的代码中散布大量的GC.Collect
没有意义,因为这就是拥有垃圾回收器的全部意义 - 不必担心自己清理东西。GC.Collect()
(你不应该这样做)。IDisposable
接口允许您使用using
模式,确保重要资源被释放(这与销毁对象不同!所有IDisposable
所做的就是确保在using
块退出时调用Dispose()
,以便您可以清理重要的东西,但对象仍然存活 - 这是一个重要的区别)。IDisposable
的示例包括终结器,但实际上不应该)。 - Sam Harwell一个类无法将自己设置为 null,因为它无法控制谁引用它。 例如,如果您在代码中有一个带有对象的变量,该对象无法在您的代码中将自己设置为 null,它只能将其自己的成员设置为 null。
此外,想象一种情况,多个类引用同一个对象,那么它在哪里设置为 null? 这是包含该对象的类应该做的事情。
Object oTest = new Object;
oTest = null;
Dispose模式仅在使用非CLR资源(如图形上下文或低级io)时才需要。有一些边缘情况需要立即释放资源,但是正如你所说,作为初学者,你真的不应该费心(至少现在不用)。
将this
设置为nil并没有帮助。考虑这个:
MyClass sample = new MyClass();
sample.Dispose();
// at this point, sample still has a value
当你想要在C#中摆脱一个对象时,你只需要让所有引用超出范围,或将它们设置为nil。(多个变量可以引用同一个实例)。运行时会自动释放对象(及其子对象),因为没有人再使用它了。
粗略地说,你可以把它们看作指针(技术上它们不是,但我们在这里试图解释原理)
IDisposable
接口的其他类,那么实现 IDisposable
接口也是一个好主意。例如,如果您将流放入类的私有字段中,则该类应该实现 IDisposable
接口,以便可以在流上调用 Dispose()
方法。 - Daniel Mann你不能修改自己的 this
指针。在你的示例中,你的 Dispose 方法不需要进行任何操作,因此可以完全省略它(以及更新类以不再实现 IDisposable
)
null
。 - Daniel Mann
this
设置为null
的内容,请告诉我们您读到的地方。我们应该避免使用您提供的来源。 - John Saundersthis = x;
,其中x
是您结构体的另一个值(x
可能是一个参数)。您可以将this
视为一种ref
参数(甚至在结构体的实例构造函数的情况下,它也可以是一个out
参数)。 - Jeppe Stig Nielsenstruct Triple { public int X; public int Y; public int Z; public Triple(int x, int y, int z) { Triple t; t.X = x; t.Y = y; t.Z = z; this = t; } public void Rotate() { this = new Triple(Y, Z, X); } }
这样编码是一种可能的做法,如果你真的想要一个可变的值类型。当然实例构造函数有点愚蠢,因为你可以直接赋值this
的X
、Y
和Z
,就像在实例构造函数中通常做的那样。但请注意,t
可以以“逐步”的方式赋值。但在方法内部,也许我找到了一个好用途? - Jeppe Stig Nielsen