Reputation: 67
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;
}
}
Upvotes: 4
Views: 307
Reputation: 11439
Your question really seems to boild down to 'How do I delete stuff in C#'. The short answer is you can't, that's the job of the Garbage Collector System.GC
. The IDisposable
inerface is used to ensure that imporant resources that don't belong to .Net (like files, or network/database connections, but not a .Net class), are cleaned up on demand.
The IDisposable
interface is important because it allows you to use the using
pattern. That is, if your class implements IDisposable
it can be used in a using
block. Consider for instance:
class MyClass : IDisposable {
public void Dispose() { }
}
this class can now be used like this:
using (MyClass instance = new MyClass())
{
} // instance.Dispose() is called here at the end of the block.
The point of the using block is that when the block ends, it the compiler will throw in a call to Dispose()
which you can use to get rid of important resources like files and database connections. For example, all of the Stream
classes, like FileStream
and what not implement IDisposable
because it's a bad idea to leave a file open. Instead, you wrap all of your access in a using
block, and then you are guaranteed that FileStream.Dispose
will close the file out. Consider:
using (FileStream myFile = File.OpenRead("..."))
{
// Read the content of the file.
} // The file is guaranteed to be closed here. Cool!
This is much neater than doing something like this:
FileStream stream = File.OpenRead(" ... ");
stream.Close(); // Yes, you closed it manually, but it's error prone. What if you forget to do this?
Now what you're thinking of is a term called "Finalization", that is when the class is actually destroyed. This happens when the garbage collector (the System.GC
class) actually destroys objects and cleans up their memory. Consider:
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();
}
}
In short, the Garbage collector is the part of the runtime that cleans up stuff that isn't being used. What does it mean to not be used? It means that there are no references attached to the object. For example, if you run the program above, you'll notice that the word "Destroyed" gets printed on the screen twice. That's because two of the instances of MyClass
created in the Main
function are not pointed to by reference (A WeakReference
is essentially the same thing as no reference). When we call GC.Collect()
the garbage collector runs and cleans up the references.
That said, you should NOT call GC.Collect
on your own. You can, for experimentation and education of course, but most people will tell you that the garbage collector does a fine job of keeping things clean on it's own. It doesn't make sense to have a bunch of GC.Collect
scattered throughout your code, because that's the whole point of having a Garbage collector - to not have to worry about cleaning things up yourself.
So in short, you really can't destroy objects on your own, unless you call GC.Collect()
(which you shouldn't do). The IDisposable
interface allows you to work with the using
pattern, ensuring that important resources are released (This is not the same thing as destroying the object though! All IDisposable
does is ensure that Dispose()
is called when the using
block exits so you can clean up important stuff, but the object is still alive - an important distinction).
Upvotes: 5
Reputation: 306
The simple answer is that the "this" keyword is read only and can't be set.
A longer more fundamental answer is that you can't set objects themselves to null in c#, however you can set the reference to an object to null. When you set an object's reference to null and nothing else references that object, that is when the object is in a state to be garbage collected. (This is a simplification of what actually occurs.)
For example:
Object oTest = new Object;
oTest = null;
In the example above the object still exists after its reference oTest has been set to null. Its simply waiting for the garbage collector to come around and delete it.
So in your code it looks like your trying to set all of your references to your object equal to null, even if that may not be what your intending. This can't be done from the object itself. You need to make sure that all of the reference to your object are manually set to null or they are guaranteed to leave scope in your program.
Upvotes: 1
Reputation: 1148
Dispose pattern is only needed when you use non-CLR resources, like graphics contexts or low level io. There are edge cases when you need to free up resources now, but as you say you are a beginner you really should not bother (yet).
Setting this
to nil does not help. Consider this
MyClass sample = new MyClass();
sample.Dispose();
// at this point, sample still has a value
When you want to get rid of an object in C#, all you need is to let all the references go out of scope, or set them to nil. (Multiple variables can refer to the same instance). The runtime will free the object (and its subobjects) automatically because nobody is using it anymore.
Roughly speaking, you can think of them as pointers (technically they are not, but we are trying to explain the principle here)
Upvotes: 0
Reputation: 5442
A class cannot make itself null because it has no control of who is referencing it. For example, if you have a variable with an object in your code, that object cannot make itself null in YOUR code, it can only set it's OWN members to null.
In addition to this, think of a case where multiple classes reference the same object, where would he be null? This is the kind of things the containing class should do.
Upvotes: 1
Reputation: 58981
The purpose of the Dispose
method isn't to clean up that class, but to clean up the disposable dependencies that the class is holding on to so that it can be disposed of normally by the garbage collector.
I'd suggest reading up more on the Dispose
pattern and how to implement it in C#.
A bit of pedantry: The Dispose
method is not a destructor, nor is it a finalizer.
Upvotes: 9
Reputation: 38130
You cannot modify your this
pointer. In your example, your Dispose method doesn't need to do anything, so could be omitted altogether (along with updating the class to no longer implement IDisposable
)
Upvotes: 0