Using `using (...)` is effectively useless and / or inefficient?

Does the following function code / t 20> invalidate?
Could this cause a flaw in the GC?

class Program { static Dictionary<string , DisposableClass> Disposables { get { if (disposables == null) disposables = new Dictionary<string , DisposableClass>(); return disposables; } } static Dictionary<string , DisposableClass> disposables; static void Main(string[] args) { DisposableClass disposable; using (disposable = new DisposableClass()) { // do some work disposable.Name = "SuperDisposable"; Disposables["uniqueID" + Disposables.Count] = disposable; } Console.WriteLine("Output: " + Disposables["uniqueID0"].Name); Console.ReadLine(); } } class DisposableClass : IDisposable { internal string Name { get { return myName; } set { myName = value; } } private string myName; public void Dispose( ) { //throw new NotImplementedException(); } } 

Output: SuperDisposable

My understanding of the using(...) function is to force the disposition of DisposableClass immediately. However, inside the code block, we add the class to the dictionary collection. I understand that a class is essentially a reference type. So my experiment was to see what would happen to a one-time item added to the collection in this way.

In this case, the DisposableClass is still quite lively. Classes are a reference type - therefore, my assumption was then that the collection not only refers to this type, but really contains the class as a value. But that also made no sense.

So what is going on?

EDIT: A modified code with exit to prove that the object is not dead, which may be suggested by some answers.

2nd EDIT: what's connected with this as I went through another code:

  public void Dispose( ) { Dispose(true); GC.SuppressFinalize(this); } private void Dispose(bool dispose) { if (!isDisposed) { if (dispose) { // clean up managed objects } // clean up unmanaged objects isDisposed = true; } } ~DisposableClass( ) { Dispose(false); } 

Code execution (had a breakpoint with private void Dispose(bool dispose) ), where false is passed to the method, it becomes necessary that the resources are properly disposed of here. Despite this, the class is still alive, but you are definitely setting yourself up for exceptions. The answers made me more curious ...

+4
source share
4 answers

Disposal of an object does not destroy it; he simply tells him to clean up any unmanaged resources that he uses, since they are no longer needed. In your example, you create a one-time object by assigning a dictionary and then simply pointing to it to delete some resources.

The correct script for the using statement is when you want to initialize a resource, do something with it, and then destroy it and forget about it; eg:

 using (var stream = new FileStream("some-file.txt")) using (var reader = new StreamReader(stream)) { Console.Write(reader.ReadToEnd()); } 

If you want to save an object after using it, you should not dispose of it, and therefore the using statement should not be used.

+11
source

In this case, you should not use the using block, since you need an object after the block completes. It should be used only when there is a clear starting and ending point in the lifetime of the object.

+2
source

It is important to remember that IDisposable, although a slightly special interface, is an interface nonetheless. When the used block exits, it calls Dispose () on your object. Nothing more. Your link is still valid and if your Dispose method does nothing, your object will not be completely affected. If you do not track deletion and throw exceptions explicitly, then after that you will not get any exceptions, because in .NET there is no built-in state.

+2
source

The IDisposable interface indicates that the type controls some resource. There is Dispose so you can get rid of the resources used by the instance without having to wait for garbage collection and resources that will be freed by the finalizer.

In your example, the dictionary still contains a reference to a one-time class, but the instance will be placed at the end of the using block. Subsequent attempts to call methods on the instance will now likely throw an ObjectDisposedException or InvalidOperationException to indicate that the instance is no longer in a "working" state.

Removing IDisposable should not be confused with freeing up the memory occupied by the instance, or invoking any garbage collection routines. An instance is monitored and managed by the garbage collector, just like any other, only to release it when the garbage collector solves it.

+1
source

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


All Articles