public class Id : IEquatable<Id>, IComparable, IComparable<Id> {
private Nullable<long>[] keyCollection;
public Id(Nullable<long> value) {
keyCollection = new Nullable<long>[1] { value };
}
public Id(params long[] values) {
if (values == null) throw new ArgumentNullException();
keyCollection = new Nullable<long>[values.Length];
for (int i = 0; i < values.Length; i++) {
keyCollection[i] = values[i];
}
}
public Nullable<long> ValueOf(int index) {
return keyCollection[index];
}
public Nullable<long> Value {
get {
if (keyCollection.Length > 1) {
throw new ArgumentException(Resources.Id.CannotGetValueOnCompositeIDs);
}
return keyCollection[0];
}
}
public int Length {
get { return keyCollection.Length; }
}
public bool IsSingleId {
get { return keyCollection.Length == 1; }
}
public int CompareTo(object obj) {
if (obj == null) {
return 1;
}
if (!(obj is Id)) {
throw new ArgumentException(Resources.Id.ArgumentMustBeID);
}
return CompareTo((Id)obj);
}
public bool HasValue {
get {
foreach (Nullable<long> key in keyCollection) {
if (key.HasValue) {
return true;
}
}
return false;
}
}
public int CompareTo(Id other) {
if (!IsSingleId || !other.IsSingleId) {
throw new InvalidOperationException(Resources.Id.CannotCompareCompositeIDs);
}
return Nullable.Compare<long>(keyCollection[0], other.Value);
}
public override bool Equals(object obj) {
return (obj is Id) && Equals((Id)obj);
}
public bool Equals(Id other) {
if (ReferenceEquals(other, null)) return false;
if (IsSingleId && !other.IsSingleId || !IsSingleId && other.IsSingleId) return false;
return EvaluateNonNullEquality(this, other);
}
public static bool operator ==(Id first, Id second) {
if (ReferenceEquals(first, second)) return true;
if (ReferenceEquals(first, null) || ReferenceEquals(second, null)) return false;
return EvaluateNonNullEquality(first, second);
}
public static bool operator !=(Id first, Id second) {
return !first.Equals(second);
}
private static bool EvaluateNonNullEquality(Id first, Id second) {
if (first.Length != second.Length) return false;
for (int i = 0; i < first.Length; i++) {
if (!first.ValueOf(i).Equals(second.ValueOf(i))) return false;
}
return true;
}
public override int GetHashCode() {
int hashCode = 0;
foreach (Nullable<long> value in keyCollection) {
hashCode = hashCode ^ value.GetHashCode();
}
return hashCode;
}
public static implicit operator Id(Nullable<long> value) {
return new Id(value);
}
public static implicit operator Id(long[] values) {
return new Id(values);
}
}