4

I am a beginner in C#, I don't know why this isn't working, I just want to set this object to null by calling Dispose() method.

Why this is not possible?

class MyClass:IDisposable
{

    public void Dispose()
    {
        this = null;
    }

}
4

6 回答 6

9

Dispose方法的目的不是清理该类,而是清理该类所持有的一次性依赖项,以便垃圾收集器可以正常处理它。

我建议阅读更多关于该Dispose模式以及如何在 C# 中实现它的信息。

有点迂腐:该Dispose方法不是析构函数,也不是终结器。

于 2013-07-27T17:56:31.653 回答
5

您的问题似乎真的可以归结为“如何删除 C# 中的内容”。简短的回答是你不能,这是垃圾收集器的工作System.GCIDisposable接口用于确保按需清理不属于 .Net的重要资源(如文件或网络/数据库连接,但不属于 .Net 类)。

界面很重要,IDisposable因为它允许您使用该using模式。也就是说,如果你的类实现IDisposable了它可以在一个using块中使用。例如考虑:

class MyClass : IDisposable {
    public void Dispose() { }
}

这个类现在可以像这样使用:

using (MyClass instance = new MyClass())
{

} // instance.Dispose() is called here at the end of the block.

using 块的要点是,当块结束时,编译器将抛出一个调用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();
    }
}

简而言之,垃圾收集器是运行时的一部分,用于清理未使用的东西。不被使用是什么意思?这意味着没有附加到对象的引用。例如,如果你运行上面的程序,你会注意到“Destroyed”这个词在屏幕上打印了两次。这是因为函数中MyClasscreated的两个实例Main没有被引用指向(AWeakReference本质上与无引用相同)。当我们调用GC.Collect()垃圾收集器时,它会运行并清理引用。

也就是说,你不应该自己GC.Collect打电话。当然,您可以进行实验和教育,但大多数人会告诉您,垃圾收集器在自己保持清洁方面做得很好。在你的代码中散落一堆是没有意义的GC.Collect,因为这就是拥有垃圾收集器的全部意义——不必担心自己清理东西。

所以简而言之,你真的不能自己销毁对象,除非你打电话GC.Collect()(你不应该这样做)。该IDisposable接口允许您使用该using模式,确保释放重要资源(但这与销毁对象不同!IDisposable所做的只是确保Dispose()在块退出时调用它,using以便您可以清理重要的东西,但是对象还活着 - 一个重要的区别)。

于 2013-07-27T18:00:47.300 回答
1

一个类不能使自己为空,因为它无法控制谁在引用它。例如,如果您的代码中有一个带有对象的变量,则该对象不能在您的代码中使自己为空,它只能将其 OWN 成员设置为空。

除此之外,想想多个类引用同一个对象的情况,他会在哪里为空?这是包含类应该做的事情。

于 2013-07-27T17:58:36.697 回答
1

简单的答案是“this”关键字是只读的,不能设置。

一个更长更基本的答案是您不能在 c# 中将对象本身设置为 null,但是您可以将对对象的引用设置为 null。当您将对象的引用设置为 null 并且没有其他对象引用该对象时,即该对象处于垃圾收集状态。(这是对实际发生的事情的简化。)

例如:

Object oTest = new Object;
oTest = null;

在上面的示例中,对象在其引用 oTest 设置为 null 后仍然存在。它只是在等待垃圾收集器出现并删除它。

因此,在您的代码中,您似乎试图将所有对对象的引用设置为 null,即使这可能不是您想要的。这不能从对象本身完成。您需要确保对您的对象的所有引用都手动设置为 null 或者保证它们在您的程序中保留范围。

空(C# 参考)

这个(C# 参考)

于 2013-07-27T18:22:18.667 回答
0

仅当您使用非 CLR 资源时才需要 Dispose 模式,例如图形上下文或低级 io。当你现在需要释放资源时会有一些极端情况,但正如你所说的你是一个初学者,你真的不应该打扰(还)。

设置this为零没有帮助。考虑这个

MyClass sample = new MyClass();
sample.Dispose();
// at this point, sample still has a value

当你想在 C# 中删除一个对象时,你只需要让所有的引用都超出范围,或者将它们设置为 nil。(多个变量可以引用同一个实例)。运行时将自动释放对象(及其子对象),因为没有人再使用它了。

粗略地说,您可以将它们视为指针(技术上它们不是,但我们在这里试图解释原理)

于 2013-07-27T18:00:35.730 回答
0

你不能修改你的this指针。在您的示例中,您的 Dispose 方法不需要执行任何操作,因此可以完全省略(以及更新类以不再实现IDisposable

于 2013-07-27T17:54:57.947 回答