Sunday 1 April 2012

Equality of Foo

image


#region Namespaces

using System;
using System.Collections;
using System.Collections.Generic;

#endregion

namespace Equality
{
public class Foo : IComparable,
IComparable<Foo>,
IEquatable<Foo>
{
#region Fields and Properties

private readonly string name;
public string Name { get { return name; } }

private readonly int value;
public int Value { get { return value; } }

#endregion

#region Constructor

public Foo(string name, int value)
{
this.name = name;
this.value = value;
}

#endregion

#region Object Overrides

public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != typeof(Foo)) return false;
return Equals((Foo)obj);
}

public override int GetHashCode()
{
unchecked
{
return ((name != null ? name.GetHashCode() : 0) * 397) ^ value;
}
}

#endregion

#region Operators

public static bool operator ==(Foo left, Foo right)
{
return object.Equals(left, right);
}

public static bool operator !=(Foo left, Foo right)
{
return !(left == right);
}

#endregion

#region Implementation of IComparable

// internalizes the comparison, automatically used by Array.Sort and ArrayList.Sort

public int CompareTo(object obj)
{
return CompareTo(obj as Foo);
}

#endregion

#region Implementation of IComparable<in Foo>

// internalizes the comparison, automatically used by Array.Sort and ArrayList.Sort
public int CompareTo(Foo other)
{
if (other == null) return 1;

return String.CompareOrdinal(Name, other.Name);
}

#endregion

#region Implementation of IEquatable<Foo>

public bool Equals(Foo other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return Equals(other.name, name) && other.value == value;
}

#endregion
}

public class FooNameInsensitiveComparer : IComparer,
IComparer<Foo>
{
#region Implementation of IComparer

public int Compare(object x, object y)
{
Foo foo1, foo2;

if (x is Foo)
foo1 = x as Foo;
else
throw new ArgumentException("Object x is not of type Foo.");

if (y is Foo)
foo2 = y as Foo;
else
throw new ArgumentException("Object y is not of type Foo.");

return Compare(foo1, foo2);
}

#endregion

#region Implementation of IComparer<in Foo>

public int Compare(Foo x, Foo y)
{
return ((new CaseInsensitiveComparer()).Compare(y.Name, x.Name));
}

#endregion
}

public class FooEqualityComparer : EqualityComparer<Foo>
{
#region Overrides of EqualityComparer<Foo>

public override bool Equals(Foo x, Foo y)
{
if (x == null || y == null)
return false;

return x.Name == y.Name && x.Value == y.Value;
}

public override int GetHashCode(Foo obj)
{
if (obj == null)
throw new ArgumentNullException();

int hash = 17;
hash = hash * 31 + (obj.Name == null ? 0 : obj.Name.GetHashCode());
hash = hash * 31 + obj.Value;
return hash;
}

#endregion
}
}

No comments:

Post a Comment