Csharp/C Sharp/Class Interface/IDisposable
Версия от 15:31, 26 мая 2010; (обсуждение)
Содержание
- 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
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();
}
}
Protecting Against Double Disposal
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();
}
}
The constructor initializes the internal object. The Dispose method closes the file resource. The destructor delegates to the Dispose method.
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();
}
}
The Dispose Pattern
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();
}
}
The IDisposable Interface
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));
}
}
}
using statement with IDisposable interface
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();
}
}