Skip to content

Instantly share code, notes, and snippets.

@GaProgMan
Last active April 24, 2019 07:49
Show Gist options
  • Save GaProgMan/fb3d6c7b550d2bc225f6 to your computer and use it in GitHub Desktop.
Save GaProgMan/fb3d6c7b550d2bc225f6 to your computer and use it in GitHub Desktop.
An example of how to over load the ==, !=, Equals and GetHashCode operators and methods for a custom class in C#
using System;
namespace ScratchPad
{
public class Foo
{
private string _name;
private string _title;
private string _address;
private bool _contacted;
/// <summary>
/// Used to check for eqaulity (long way) between two Foo objects.
/// Each element of the Foo objects is compared, if they match we
/// return true, otherwise we return false
/// </summary>
/// <param name="leftHand">The left hand Foo object</param>
/// <param name="rightHand">The right hand Foo object</param>
/// <returns>Whether the two Foo objects are equal</returns>
public static bool operator == (Foo leftHand, Foo rightHand)
{
if (leftHand._name == rightHand._name &&
leftHand._title == rightHand._title &&
leftHand._address == rightHand._address &&
leftHand._contacted == rightHand._contacted)
return true;
return false;
}
/// <summary>
/// Used to check for negative equality (long way) of two Foo objects.
/// Calls the == operator with the two Foo objects and negates the
/// returned value.
/// </summary>
/// <param name="leftHand">The left hand Foo object</param>
/// <param name="rightHand">The right hand Foo object</param>
/// <returns>Whether the two Foo objects are not equal</returns>
public static bool operator !=(Foo leftHand, Foo rightHand)
{
return !(leftHand == rightHand);
}
/// <summary>
/// Used to generate a hash code for this object. This is required
/// for testing equality if the Foo objects are stored in
/// a list.
/// It generates a sum of all characters used in each string and XORs
/// each total against the initial hash (set to a prime number to
/// help avoid has collisions).
/// The theory is that no two Foo objects will have the same
/// unless all of their properties have the same values
/// </summary>
/// <returns>The hash of this instance of the object</returns>
public override int GetHashCode()
{
int hash = 13; // start with a prime number to make collisions less frequent
hash = hash ^ SumCharValuesFromString(_name);
hash = hash ^ SumCharValuesFromString(_title);
hash = hash ^ SumCharValuesFromString(_address);
hash = hash ^ (_contacted ? 1 : 0); // if _contacted is true, we XOR with 1
return hash;
}
/// <summary>
/// Used to get a sum of all characters used in a given string.
/// This is used by the GetHasCode method to get the hash code
/// of the object, based on the value of the
/// </summary>
/// <param name="inString">The string to generate the char sum of</param>
/// <returns>The char sum of all characters in the given string</returns>
private int SumCharValuesFromString(string inString)
{
int sum = 0;
foreach (char individualChar in inString)
{
sum += (int)individualChar;
}
return sum;
}
/// <summary>
/// Used to check for equality of two Foo objects (1 via
/// dot access [this] and one that is passed in) using the Equals
/// operator
/// </summary>
/// <param name="obj">the object to compare equality with this [dot access] Foo</param>
/// <returns>Whether the two objects are equal or not</returns>
public override bool Equals(object obj)
{
// Parse the passed in object as a Foo object and check
// that it actually is a Foo object first. If we don't
// perform this check, then the object could be null which will
// make further operation return null.
Foo req = obj as Foo;
if ((object)req == null)
{
return false;
}
// We can assume that obj is an actual Foo object. Now
// to perform the actual equality check.
// Get the hash code of the Foo object we're dot accessing
// and the hash code of the object we've passed in, compare them
// for equality and return their value
return this.GetHashCode() == req.GetHashCode();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment