Skip to content

Instantly share code, notes, and snippets.

@canton7
Last active March 19, 2019 17:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save canton7/df27f45b6d49445507e90261e250277a to your computer and use it in GitHub Desktop.
Save canton7/df27f45b6d49445507e90261e250277a to your computer and use it in GitHub Desktop.
public readonly struct EquatableStruct : IEquatable<EquatableStruct>
{
private readonly float valueMember;
private readonly Version referenceMember;
public bool Equals(EquatableStruct other)
{
// Compare value types using == (or .Equals)
// Compare reference types for equality using Equals(object, object)
// to be safe to null references.
return valueMember == other.valueMember &&
Equals(referenceMember, other.referenceMember);
}
public override int GetHashCode()
{
unchecked
{
int hash = 17;
hash = hash * 23 + valueMember.GetHashCode();
// Be careful of null references on reference types
hash = hash * 23 + referenceMember?.GetHashCode() ?? 0;
return hash;
}
}
public override bool Equals(object obj) => obj is EquatableStruct other && Equals(other);
public static bool operator ==(EquatableStruct x, EquatableStruct y) => x.Equals(y);
public static bool operator !=(EquatableStruct x, EquatableStruct y) => !x.Equals(y);
}
public readonly struct ComparableStruct : IEquatable<ComparableStruct>, IComparable<ComparableStruct>
{
private readonly float valueMember;
private readonly Version referenceMember;
public int CompareTo(ComparableStruct other)
{
int result = valueMember.CompareTo(other.valueMember);
if (result == 0)
{
result = Comparer<Version>.Default.Compare(referenceMember, other.referenceMember);
}
return result;
}
public override int GetHashCode()
{
unchecked
{
int hash = 17;
hash = hash * 23 + valueMember.GetHashCode();
// Be careful of null references on reference types
hash = hash * 23 + referenceMember?.GetHashCode() ?? 0;
return hash;
}
}
public bool Equals(ComparableStruct other) => CompareTo(other) == 0;
public override bool Equals(object obj) => obj is ComparableStruct other && CompareTo(other) == 0;
public static bool operator ==(ComparableStruct x, ComparableStruct y) => x.CompareTo(y) == 0;
public static bool operator !=(ComparableStruct x, ComparableStruct y) => x.CompareTo(y) != 0;
public static bool operator >(ComparableStruct x, ComparableStruct y) => x.CompareTo(y) > 0;
public static bool operator >=(ComparableStruct x, ComparableStruct y) => x.CompareTo(y) >= 0;
public static bool operator <(ComparableStruct x, ComparableStruct y) => x.CompareTo(y) < 0;
public static bool operator <=(ComparableStruct x, ComparableStruct y) => x.CompareTo(y) <= 0;
}
public sealed class EquatableSealedClass
{
private readonly float valueMember;
private readonly Version referenceMember;
public override bool Equals(object obj)
{
var other = obj as EquatableSealedClass;
if (other is null)
return false;
if (ReferenceEquals(this, other))
return true;
return valueMember == other.valueMember &&
Equals(referenceMember, other.referenceMember);
}
public override int GetHashCode()
{
unchecked
{
int hash = 17;
hash = hash * 23 + valueMember.GetHashCode();
// Be careful of null references on reference types
hash = hash * 23 + referenceMember?.GetHashCode() ?? 0;
return hash;
}
}
// Define these ONLY for types that don't have reference semantics
public static bool operator ==(EquatableSealedClass x, EquatableSealedClass y) => Equals(x, y);
public static bool operator !=(EquatableSealedClass x, EquatableSealedClass y) => !Equals(x, y);
}
public class EquatableUnsealedClass
{
private readonly float valueMember;
private readonly Version referenceMember;
public override bool Equals(object obj)
{
if (obj is null)
return false;
if (ReferenceEquals(this, obj))
return true;
if (this.GetType() != obj.GetType())
return false;
var other = (EquatableUnsealedClass)obj;
return valueMember == other.valueMember &&
Equals(referenceMember, other.referenceMember);
}
public override int GetHashCode()
{
unchecked
{
int hash = 17;
hash = hash * 23 + valueMember.GetHashCode();
// Be careful of null references on reference types
hash = hash * 23 + referenceMember?.GetHashCode() ?? 0;
return hash;
}
}
// Define these ONLY for types that don't have reference semantics
public static bool operator ==(EquatableUnsealedClass x, EquatableUnsealedClass y) => Equals(x, y);
public static bool operator !=(EquatableUnsealedClass x, EquatableUnsealedClass y) => !Equals(x, y);
}
public sealed class ComparableSealedClass : IComparable<ComparableSealedClass>
{
private readonly float valueMember;
private readonly Version referenceMember;
public int CompareTo(ComparableSealedClass other)
{
if (other is null)
return 1;
if (ReferenceEquals(this, other))
return 0;
int result = valueMember.CompareTo(other.valueMember);
if (result == 0)
{
// Takes care of null references
result = Comparer<Version>.Default.Compare(referenceMember, other.referenceMember);
}
return result;
}
public override int GetHashCode()
{
unchecked
{
int hash = 17;
hash = hash * 23 + valueMember.GetHashCode();
// Be careful of null references on reference types
hash = hash * 23 + referenceMember?.GetHashCode() ?? 0;
return hash;
}
}
public override bool Equals(object obj) => obj is ComparableSealedClass other && CompareTo(other) == 0;
// Helper to reduce boilerplate below. Takes care of null references
private static int Compare(ComparableSealedClass x, ComparableSealedClass y) =>
Comparer<ComparableSealedClass>.Default.Compare(x, y);
public static bool operator ==(ComparableSealedClass x, ComparableSealedClass y) => Compare(x, y) == 0;
public static bool operator !=(ComparableSealedClass x, ComparableSealedClass y) => Compare(x, y) != 0;
public static bool operator >(ComparableSealedClass x, ComparableSealedClass y) => Compare(x, y) > 0;
public static bool operator >=(ComparableSealedClass x, ComparableSealedClass y) => Compare(x, y) >= 0;
public static bool operator <(ComparableSealedClass x, ComparableSealedClass y) => Compare(x, y) < 0;
public static bool operator <=(ComparableSealedClass x, ComparableSealedClass y) => Compare(x, y) <= 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment