Csharp/C Sharp/Class Interface/IDisposable
Содержание
- 1 Derived Disposable Classes
- 2 Protecting Against Double Disposal
- 3 The constructor initializes the internal object. The Dispose method closes the file resource. The destructor delegates to the Dispose method.
- 4 The Dispose Pattern
- 5 The IDisposable Interface
- 6 using statement with IDisposable interface
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>