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(); } }
Class Interface
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(); } }
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(); } }
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(); } }
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)); } } } [/csharp]
Implements ICustomFormatter
using System; using System.Text; using System.Globalization; public class WordyFormatProvider : IFormatProvider, ICustomFormatter { static readonly string[] _numberWords = "zero one two three four five six seven eight nine minus point".Split(); IFormatProvider _parent; // Allows consumers to chain format providers public WordyFormatProvider() : this(CultureInfo.CurrentCulture) { } public WordyFormatProvider(IFormatProvider parent) { _parent = parent; } public object GetFormat(Type formatType) { if (formatType == typeof(ICustomFormatter)) return this; return null; } public string Format(string format, object arg, IFormatProvider prov) { if (arg == null || format != "W") return string.Format(_parent, "{0:" + format + "}", arg); StringBuilder result = new StringBuilder(); string digitList = string.Format(CultureInfo.InvariantCulture, "{0}", arg); foreach (char digit in digitList) { int i = "0123456789-.".IndexOf(digit); if (i == -1) continue; if (result.Length > 0) result.Append(' '); result.Append(_numberWords[i]); } return result.ToString(); } } public class MainClass { public static void Main() { double n = -123.45; IFormatProvider fp = new WordyFormatProvider(); Console.WriteLine(string.Format(fp, "{0:C} in words is {0:W}", n)); } }
Gets the hash code for an object using a comparer. Correctly handles null.
//****************************** // Written by Peter Golde // Copyright (c) 2004-2007, Wintellect // // Use and restribution of this code is subject to the license agreement // contained in the file "License.txt" accompanying this file. //****************************** using System; using System.Collections; using System.Collections.Generic; namespace Wintellect.PowerCollections { /// <summary> /// A holder class for various internal utility functions that need to be shared. /// </summary> internal static class Util { /// <summary> /// Gets the hash code for an object using a comparer. Correctly handles /// null. /// </summary> /// <param name="item">Item to get hash code for. Can be null.</param> /// <param name="equalityComparer">The comparer to use.</param> /// <returns>The hash code for the item.</returns> public static int GetHashCode<T>(T item, IEqualityComparer<T> equalityComparer) { if (item == null) return 0x1786E23C; else return equalityComparer.GetHashCode(item); } } }