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