Csharp/C Sharp/Class Interface/IDisposable

Материал из .Net Framework эксперт
Перейти к: навигация, поиск

Derived Disposable Classes

<source lang="csharp"> using System; public class MyClass : IDisposable {

   protected string name;
   public MyClass(string name) { this.name = name; }
   override public string ToString() { return name; }
   ~MyClass() { Dispose(); Console.WriteLine("~MyClass()"); }
   public void Dispose() 
   { 
       Console.WriteLine("MyClass.Dispose()"); 
       GC.SuppressFinalize(this);
   }

} public class SonOfMyClass : MyClass, IDisposable {

   public SonOfMyClass(string name) : base(name) { }
   override public string ToString() { 
      return name; 
   }
   ~SonOfMyClass() { 
      Dispose(); 
      Console.WriteLine("~SonOfMyClass()"); 
   }
   new public void Dispose()
   { 
       base.Dispose();
       GC.SuppressFinalize(this);
   }

}

class DerivedDisposeApp {

   static void Main(string[] args)
   {
       DoSomething();
   }
   static void DoSomething()
   {
       SonOfMyClass s = new SonOfMyClass("Bar");
       Console.WriteLine(s);
       s.Dispose();
   }

}

</source>


Protecting Against Double Disposal

<source lang="csharp"> using System; public class MyClass : IDisposable {

   private string name;
   public MyClass(string name) { this.name = name; }
   override public string ToString() { return name; }
  
   ~MyClass() 
   { 
       Dispose();
       Console.WriteLine("~MyClass()"); 
   }
  
   private bool AlreadyDisposed = false;
  
   public void Dispose()
   {
       if (!AlreadyDisposed)
       {
           AlreadyDisposed = true;
           Console.WriteLine("Dispose()");
           GC.SuppressFinalize(this);
       }
   }

}

public class MainClass {

   public static void Main(string[] args)
   {
       MyClass t = new MyClass("Foo");
       Console.WriteLine(t);
  
       t.Dispose();
       t.Dispose();
  
       GC.Collect();
       GC.WaitForPendingFinalizers();
   }

}

</source>


The constructor initializes the internal object. The Dispose method closes the file resource. The destructor delegates to the Dispose method.

<source lang="csharp"> using System; using System.IO;

public class WriteToFile : IDisposable {

   public WriteToFile(string _file, string _text) {
       file = new StreamWriter(_file, true);
       text = _text;
   }
   public void WriteText() {
       file.WriteLine(text);
   }
   public void Dispose() {
       file.Close();
   }
   ~WriteToFile() {
       Dispose();
   }
   private StreamWriter file;
   private string text;

} public class Writer {

   public static void Main() {
       WriteToFile sample = new WriteToFile("sample.txt", "My text file");
       sample.WriteText();
       sample.Dispose();
   }

}

</source>


The Dispose Pattern

<source lang="csharp"> using System;

public class MyClass {

   private string name;
   public MyClass(string name) { this.name = name; }
   override public string ToString() { return name; }
   ~MyClass() { Console.WriteLine("~MyClass()"); }
   public void Dispose() {
       Console.WriteLine("Dispose()");
   }

} public class GarbageDisposalApp {

   public static void Main(string[] args) {
       DoSomething();
       Console.WriteLine("end of Main");
   }
   public static void DoSomething() {
       MyClass t = new MyClass("Foo");
       Console.WriteLine(t);
       t.Dispose();
       t = null;
       GC.Collect();
       GC.WaitForPendingFinalizers();
   }

}

</source>


The IDisposable Interface

<source lang="csharp"> using System; public class MyClass : IDisposable {

   private string name;
   public MyClass(string name) { this.name = name; }
   override public string ToString() { return name; }
  
   ~MyClass() 
   { 
       Dispose();
       Console.WriteLine("~MyClass(): " +name); 
   }
  
   public void Dispose()
   {
       Console.WriteLine("Dispose(): " +name);
       GC.SuppressFinalize(this);
   }

}

public class DisposableApp {

   public static void Main(string[] args)
   {
       Console.WriteLine("start of Main, heap used: {0}", GC.GetTotalMemory(true));
       DoSomething();
       Console.WriteLine("end of Main, heap used: {0}", GC.GetTotalMemory(true));
   }
  
   public static void DoSomething()
   {
       MyClass[] ta = new MyClass[3];
  
       for (int i = 0; i < 3; i++)
       {
           ta[i] = new MyClass(String.Format("object #" +i));
           Console.WriteLine("Allocated {0} objects, heap used: {1}", i+1, GC.GetTotalMemory(true));
       }
  
       for (int i = 0; i < 3; i++)
       {
           ta[i].Dispose();
           ta[i] = null;
           GC.Collect();
           GC.WaitForPendingFinalizers();
           Console.WriteLine("Disposed {0} objects, heap used: {1}",i+1, GC.GetTotalMemory(true));
       }
   }

}

</source>


using statement with IDisposable interface

<source lang="csharp"> using System; public class MyValueReport {

   int InstanceNumber;
   public MyValueReport(int InstanceNumber) {
       this.InstanceNumber = InstanceNumber;
       Console.WriteLine(InstanceNumber);
   }

} public class MyValue : IDisposable {

   int n;
   public MyValue(int n) {
       this.n = n;
       MyValueReport MyReport = new MyValueReport(n);
   }
   public void Dispose() {
       MyValueReport MyReport = new MyValueReport(this.n);
       GC.SuppressFinalize(this); 
   }
   ~MyValue() {
       MyValueReport MyReport = new MyValueReport(this.n);
   }

} public class Test {

   static void Main() {
       MyValue d1 = new MyValue(1);
       MyValue d2 = new MyValue(2);
       MyValue d3 = new MyValue(3);
       d1 = null;
       using (d3) {
           MyValue d4 = new MyValue(4);
       }
       d2.Dispose();
   }

}

</source>