Csharp/C Sharp/Class Interface/IDisposable

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

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();
    }
}