A simple problem with the destructor (IDisposable interface)

I'm new to C #, I don't know why this doesn't work, I just want this object to be null by calling the Dispose() method.

Why is this impossible?

 class MyClass:IDisposable { public void Dispose() { this = null; } } 
+4
source share
6 answers

Your question really seems to boil down to the "How to Delete Material in C #" section. The short answer is: you cannot have the System.GC garbage collector working. IDisposable inerface is used to ensure that important resources not belonging to .Net (for example, files or network / database connections, but not the .Net class) are cleared on demand.

The IDisposable interface is important because it allows you to use the using template. That is, if your class implements IDisposable , it can be used in the using block. Consider, for example:

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

Now this class can be used as follows:

 using (MyClass instance = new MyClass()) { } // instance.Dispose() is called here at the end of the block. 

The point of the block used is that when the block ends, the compiler will call the Dispose() call, which you can use to get rid of important resources, such as files and database connections. For example, all Stream classes, such as FileStream and that do not implement IDisposable , because it is a bad idea to leave the file open. Instead, you terminate all your access in the using block, and then you are guaranteed that FileStream.Dispose will close the file. 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 error prone. What if you forget to do this? 

Now, what are you thinking about, this is a term called โ€œFinalization,โ€ that is, when a class is actually destroyed. This happens when the garbage collector ( System.GC class) actually destroys the objects and clears 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 part of a runtime that cleans up material that is not in use. What does it mean not to use? This means that there are no references to the object. For example, if you run the program above, you will notice that the word "Destroyed" is printed twice on the screen. This is because two instances of MyClass created in the Main function are not referenced (A WeakReference is essentially the same as without a reference). When we call GC.Collect() , the garbage collector starts and clears the links.

However, you should NOT call GC.Collect yourself. Of course, you can experiment and learn, but most people will tell you that the garbage collector does an excellent job of keeping things clean. It doesn't make sense to have a bunch of GC.Collect scattered all over your code, because the whole point of having a garbage collector is no need to worry about cleaning yourself.

In short, you really can't destroy objects yourself unless you name GC.Collect() (which you shouldn't do). The IDisposable interface allows you to work with the using template, ensuring that important resources are released (this is not the same as destroying an object, though! Everything IDisposable does ensures that Dispose() is called when using blocks outputs, so you can clear important ones things, but the object is still alive - an important difference).

+5
source

The purpose of the Dispose method is not to clear this class, but to clear the one-time dependencies to which the class belongs so that it can be disposed of properly by the garbage collector.

I would suggest reading more about the Dispose pattern and how to implement it in C # .

A bit of pedantry: the Dispose method is not a destructor and is not a finalizer.

+9
source

A class cannot make itself null because it does not control who references it. For example, if you have a variable with an object in your code, this object cannot make itself null in YOUR code, it can only set the OWN members to null.

In addition to this, think about the case when several classes refer to the same object, where will it be zero? This is what the class containing the class should do.

+1
source

The simple answer is that the keyword "this" is read-only and cannot be set.

A more fundamental answer is that you cannot set the objects to null in C # yourself, however you can set the object reference to null. When you set a reference to an object to null, and nothing else refers to this object, that is, when the object is in a state that needs to be garbage collected. (This is a simplification of what is actually happening.)

For instance:

 Object oTest = new Object; oTest = null; 

In the above example, the object still exists after its oTest reference has been set to null. It just waits for the garbage collector to appear and delete it.

So, in your code, it looks like you are trying to set all of your references to your object to zero, even if it may not be what you intend. This cannot be done from the object itself. You must make sure that all references to your object are manually set to zero or that they are guaranteed to leave an area in your program.

null (C # link)

this (C # link)

+1
source

You cannot change the this pointer. In your example, the Dispose method should not do anything, so it can be omitted altogether (along with updating the class that no longer implements IDisposable )

0
source

Dispose pattern is only required when using resources other than the CLR, such as graphics contexts or low io. There are extreme cases when you need to free resources now, but as you say, you are a beginner, you really should not worry (for now).

Setting this to nil does not help. Consider this

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

If you want to get rid of the object in C #, all you need is to let all links go out of scope or set them to nil. (Several variables may refer to the same instance). The runtime will release the object (and its subobjects) automatically because no one else uses it.

Roughly speaking, you can think of them as pointers (technically, this is not so, but we are trying to explain the principle here)

0
source

Source: https://habr.com/ru/post/1493831/


All Articles