Last active
March 19, 2019 17:22
-
-
Save canton7/df27f45b6d49445507e90261e250277a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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